Bash: pipe 'find' output into 'readarray'
Clash Royale CLAN TAG#URR8PPP
up vote
5
down vote
favorite
I'm trying to search for files using find
, and put those files into a Bash array so that I can do other operations on them (e.g. ls
or grep
them). But I can't figure out why readarray
isn't reading the find
output as it's piped into it.
Say I have two files in the current directory, file1.txt
and file2.txt
. So the find
output is as follows:
$ find . -name "file*"
./file1.txt
./file2.txt
So I want to pipe that into an array whose two elements are the strings "./file1.txt"
and "./file2.txt"
(without quotes, obviously).
I've tried this, among a few other things:
$ declare -a FILES
$ find . -name "file*" | readarray FILES
$ echo "$FILES[@]"; echo "$#FILES[@]"
0
As you can see from the echo
output, my array is empty.
So what exactly am I doing wrong here? Why is readarray
not reading find
's output as its standard input and putting those strings into the array?
bash find
add a comment |
up vote
5
down vote
favorite
I'm trying to search for files using find
, and put those files into a Bash array so that I can do other operations on them (e.g. ls
or grep
them). But I can't figure out why readarray
isn't reading the find
output as it's piped into it.
Say I have two files in the current directory, file1.txt
and file2.txt
. So the find
output is as follows:
$ find . -name "file*"
./file1.txt
./file2.txt
So I want to pipe that into an array whose two elements are the strings "./file1.txt"
and "./file2.txt"
(without quotes, obviously).
I've tried this, among a few other things:
$ declare -a FILES
$ find . -name "file*" | readarray FILES
$ echo "$FILES[@]"; echo "$#FILES[@]"
0
As you can see from the echo
output, my array is empty.
So what exactly am I doing wrong here? Why is readarray
not reading find
's output as its standard input and putting those strings into the array?
bash find
add a comment |
up vote
5
down vote
favorite
up vote
5
down vote
favorite
I'm trying to search for files using find
, and put those files into a Bash array so that I can do other operations on them (e.g. ls
or grep
them). But I can't figure out why readarray
isn't reading the find
output as it's piped into it.
Say I have two files in the current directory, file1.txt
and file2.txt
. So the find
output is as follows:
$ find . -name "file*"
./file1.txt
./file2.txt
So I want to pipe that into an array whose two elements are the strings "./file1.txt"
and "./file2.txt"
(without quotes, obviously).
I've tried this, among a few other things:
$ declare -a FILES
$ find . -name "file*" | readarray FILES
$ echo "$FILES[@]"; echo "$#FILES[@]"
0
As you can see from the echo
output, my array is empty.
So what exactly am I doing wrong here? Why is readarray
not reading find
's output as its standard input and putting those strings into the array?
bash find
I'm trying to search for files using find
, and put those files into a Bash array so that I can do other operations on them (e.g. ls
or grep
them). But I can't figure out why readarray
isn't reading the find
output as it's piped into it.
Say I have two files in the current directory, file1.txt
and file2.txt
. So the find
output is as follows:
$ find . -name "file*"
./file1.txt
./file2.txt
So I want to pipe that into an array whose two elements are the strings "./file1.txt"
and "./file2.txt"
(without quotes, obviously).
I've tried this, among a few other things:
$ declare -a FILES
$ find . -name "file*" | readarray FILES
$ echo "$FILES[@]"; echo "$#FILES[@]"
0
As you can see from the echo
output, my array is empty.
So what exactly am I doing wrong here? Why is readarray
not reading find
's output as its standard input and putting those strings into the array?
bash find
bash find
asked Feb 17 '16 at 16:16
villapx
21028
21028
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
up vote
12
down vote
accepted
When using a pipeline, bash runs the commands in subshells. Therefore, the array is populated, but in a subshell, so the parent shell has no access to it.
Use process substitution:
readarray FILES < <(find)
Note that it doesn't work for files with newlines in their names. If that could be the case, you need a more elaborate syntax:
readarray -d '' < <(find -print0)
Awesome. Thanks for explaining that
– villapx
Feb 17 '16 at 16:34
2
In order to support newlines, this is sufficient:readarray -d '' < <(find your_args -print0)
– VasyaNovikov
Jan 18 at 13:40
add a comment |
up vote
5
down vote
The correct solution is:
unset a; declare -a a
while IFS= read -r -u3 -d $'' file; do
a+=( "$file" ) # or however you want to process each file
done 3< <(find /tmp -type f -print0)
That's similar to what Greg's BashFAQ 020 explains in detail and this answer covers.
Has no problem with odd named files (that contain no NUL in the name), with spaces or new lines. And the result is set in an array, which makes it useful for further processing.
Great, this is a better solution to the problem I was trying to solve in the first place. +1 as soon as my rep reaches 15 :)
– villapx
Feb 17 '16 at 19:12
add a comment |
up vote
2
down vote
readarray
can also read from stdin
readarray FILES <<< "$(find . -name "file*")"; echo "$#FILES[@]"
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
12
down vote
accepted
When using a pipeline, bash runs the commands in subshells. Therefore, the array is populated, but in a subshell, so the parent shell has no access to it.
Use process substitution:
readarray FILES < <(find)
Note that it doesn't work for files with newlines in their names. If that could be the case, you need a more elaborate syntax:
readarray -d '' < <(find -print0)
Awesome. Thanks for explaining that
– villapx
Feb 17 '16 at 16:34
2
In order to support newlines, this is sufficient:readarray -d '' < <(find your_args -print0)
– VasyaNovikov
Jan 18 at 13:40
add a comment |
up vote
12
down vote
accepted
When using a pipeline, bash runs the commands in subshells. Therefore, the array is populated, but in a subshell, so the parent shell has no access to it.
Use process substitution:
readarray FILES < <(find)
Note that it doesn't work for files with newlines in their names. If that could be the case, you need a more elaborate syntax:
readarray -d '' < <(find -print0)
Awesome. Thanks for explaining that
– villapx
Feb 17 '16 at 16:34
2
In order to support newlines, this is sufficient:readarray -d '' < <(find your_args -print0)
– VasyaNovikov
Jan 18 at 13:40
add a comment |
up vote
12
down vote
accepted
up vote
12
down vote
accepted
When using a pipeline, bash runs the commands in subshells. Therefore, the array is populated, but in a subshell, so the parent shell has no access to it.
Use process substitution:
readarray FILES < <(find)
Note that it doesn't work for files with newlines in their names. If that could be the case, you need a more elaborate syntax:
readarray -d '' < <(find -print0)
When using a pipeline, bash runs the commands in subshells. Therefore, the array is populated, but in a subshell, so the parent shell has no access to it.
Use process substitution:
readarray FILES < <(find)
Note that it doesn't work for files with newlines in their names. If that could be the case, you need a more elaborate syntax:
readarray -d '' < <(find -print0)
edited Nov 26 at 8:28
answered Feb 17 '16 at 16:25
choroba
26k44570
26k44570
Awesome. Thanks for explaining that
– villapx
Feb 17 '16 at 16:34
2
In order to support newlines, this is sufficient:readarray -d '' < <(find your_args -print0)
– VasyaNovikov
Jan 18 at 13:40
add a comment |
Awesome. Thanks for explaining that
– villapx
Feb 17 '16 at 16:34
2
In order to support newlines, this is sufficient:readarray -d '' < <(find your_args -print0)
– VasyaNovikov
Jan 18 at 13:40
Awesome. Thanks for explaining that
– villapx
Feb 17 '16 at 16:34
Awesome. Thanks for explaining that
– villapx
Feb 17 '16 at 16:34
2
2
In order to support newlines, this is sufficient:
readarray -d '' < <(find your_args -print0)
– VasyaNovikov
Jan 18 at 13:40
In order to support newlines, this is sufficient:
readarray -d '' < <(find your_args -print0)
– VasyaNovikov
Jan 18 at 13:40
add a comment |
up vote
5
down vote
The correct solution is:
unset a; declare -a a
while IFS= read -r -u3 -d $'' file; do
a+=( "$file" ) # or however you want to process each file
done 3< <(find /tmp -type f -print0)
That's similar to what Greg's BashFAQ 020 explains in detail and this answer covers.
Has no problem with odd named files (that contain no NUL in the name), with spaces or new lines. And the result is set in an array, which makes it useful for further processing.
Great, this is a better solution to the problem I was trying to solve in the first place. +1 as soon as my rep reaches 15 :)
– villapx
Feb 17 '16 at 19:12
add a comment |
up vote
5
down vote
The correct solution is:
unset a; declare -a a
while IFS= read -r -u3 -d $'' file; do
a+=( "$file" ) # or however you want to process each file
done 3< <(find /tmp -type f -print0)
That's similar to what Greg's BashFAQ 020 explains in detail and this answer covers.
Has no problem with odd named files (that contain no NUL in the name), with spaces or new lines. And the result is set in an array, which makes it useful for further processing.
Great, this is a better solution to the problem I was trying to solve in the first place. +1 as soon as my rep reaches 15 :)
– villapx
Feb 17 '16 at 19:12
add a comment |
up vote
5
down vote
up vote
5
down vote
The correct solution is:
unset a; declare -a a
while IFS= read -r -u3 -d $'' file; do
a+=( "$file" ) # or however you want to process each file
done 3< <(find /tmp -type f -print0)
That's similar to what Greg's BashFAQ 020 explains in detail and this answer covers.
Has no problem with odd named files (that contain no NUL in the name), with spaces or new lines. And the result is set in an array, which makes it useful for further processing.
The correct solution is:
unset a; declare -a a
while IFS= read -r -u3 -d $'' file; do
a+=( "$file" ) # or however you want to process each file
done 3< <(find /tmp -type f -print0)
That's similar to what Greg's BashFAQ 020 explains in detail and this answer covers.
Has no problem with odd named files (that contain no NUL in the name), with spaces or new lines. And the result is set in an array, which makes it useful for further processing.
edited May 23 '17 at 12:39
Community♦
1
1
answered Feb 17 '16 at 18:40
user79743
Great, this is a better solution to the problem I was trying to solve in the first place. +1 as soon as my rep reaches 15 :)
– villapx
Feb 17 '16 at 19:12
add a comment |
Great, this is a better solution to the problem I was trying to solve in the first place. +1 as soon as my rep reaches 15 :)
– villapx
Feb 17 '16 at 19:12
Great, this is a better solution to the problem I was trying to solve in the first place. +1 as soon as my rep reaches 15 :)
– villapx
Feb 17 '16 at 19:12
Great, this is a better solution to the problem I was trying to solve in the first place. +1 as soon as my rep reaches 15 :)
– villapx
Feb 17 '16 at 19:12
add a comment |
up vote
2
down vote
readarray
can also read from stdin
readarray FILES <<< "$(find . -name "file*")"; echo "$#FILES[@]"
add a comment |
up vote
2
down vote
readarray
can also read from stdin
readarray FILES <<< "$(find . -name "file*")"; echo "$#FILES[@]"
add a comment |
up vote
2
down vote
up vote
2
down vote
readarray
can also read from stdin
readarray FILES <<< "$(find . -name "file*")"; echo "$#FILES[@]"
readarray
can also read from stdin
readarray FILES <<< "$(find . -name "file*")"; echo "$#FILES[@]"
edited Nov 11 '16 at 5:16
answered Nov 11 '16 at 5:08
smac89
19719
19719
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f263883%2fbash-pipe-find-output-into-readarray%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown