0

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.

1
  • 2
    Why are you using find? There's no difference between find *.txt and just *.txt, unless you have subdirectories with names ending in .txt. Did you mean find . -name '*.txt'? Commented May 21, 2014 at 20:28

4 Answers 4

1

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[@]}"
Sign up to request clarification or add additional context in comments.

1 Comment

Let's hope there are no spaces in the filenames... hope and pray! you daredevil!
1

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.

3 Comments

He's not even recursing through subdirectories.
Then the even simpler array=( *.txt ) can be used (which doesn't require bash 4). This replacement assumes he means to use find . -name '*.txt'.
+1 for simplicity and for being safe against hostile file names.
1

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!

Comments

0

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.