Reputation: 6275
I would like put the result of command find *.txt
in array and then iterate over the array like this
for file in array
do
done
I need to put in array because later I need to access to the array. So the solution
for file in `find *.txt`
do
done
isn't good for me.
Upvotes: 0
Views: 95
Reputation: 113934
The other answers all have virtues. As a complement to them, here is an approach which (a) is safe on even the most difficult file names, (b) allows the full use of the power of find
, and (c) avoids eval
:
array=()
while read -r -d $'\0'; do
array+=("$REPLY")
done < <(find . -name '*.txt' -print0)
Upvotes: 0
Reputation: 782130
Use array assignment syntax:
array=($(find *.txt))
If there can be spaces in the filenames, you should put
IFS=$"\n"
before the above command. If there can be newlines in the filenames, it gets really complicated and I'm not sure of a good way to handle it.
Then you can iterate over it with:
for file in "${array[@]}"
Upvotes: 1
Reputation: 46883
If you're sure that you don't have any newlines in your filenames, mapfile
is a good choice:
mapfile -t array < <(find . -name '*.txt')
Now if you want something more bullet proof, you can use:
mapfile -t array < <(find . -name '*.txt' -exec bash -c 'printf "%q\n" "${@:0}"' {} +)
eval array=( ${array[@]} )
You should feel really bad when seeing this last line: eval
and unquoted ${array[@]}
. It works and it's bullet proof since the array array
has been built using the '%q' modifier of printf
, so everything is nicely escaped or quoted so as to be used safely here!
Upvotes: 1
Reputation: 532053
If you are using bash
4, and as you don't appear to be using any other feature of find
except its ability to recurse through subdirectories, I suggest using the globstar
option instead.
shopt -s globstar
array=( **/*.txt )
This avoids spawning an external process in which to run find
, as well as avoiding any nasty surprises if any of the matching files have whitespace in their names.
Upvotes: 1