5

In linux shell scripting I am trying to set the output of find into an array as below

#!/bin/bash
arr=($(find . -type -f))

but it give error as -type should contain only one character. can anybody tell me where is the issue.

Thanks

6
  • 9
    Just remove - sign before f. arr=($(find . -type f)) Commented Aug 12, 2014 at 8:03
  • 6
    Beware of filenames containing whitespace. Commented Aug 12, 2014 at 8:11
  • 1
    But you still need to consider choroba's point, which is 100% right: filenames with spaces will be broken into several array items. Commented Aug 12, 2014 at 8:32
  • yes that exactly right now, so how can I solve that Commented Aug 12, 2014 at 8:45
  • 2
    There is a way simpler than @jaybee 's answer. Simply do IFS=$'\n' arr=($(find . -type f)). echo "${arr[X]}" will display the Xth member of the array correctly even if there are spaces in the name Commented Aug 12, 2014 at 8:53

2 Answers 2

6

If you are using bash 4, the readarray command can be used along with process substitution.

readarray -t arr < <(find . -type f)

Properly supporting all file names, including those that contain newlines, requires a bit more work, along with a version of find that supports -print0:

while read -d '' -r; do
    arr+=( "$REPLY" )
done < <(find . -type f -print0)
Sign up to request clarification or add additional context in comments.

Comments

0

I suggest the following script:

#!/bin/bash
listoffiles=$(find . -type f)
nfiles=$(echo "${listoffiles}" | wc -l)
unset myarray
for i in $(seq 1 ${nfiles}) ; do
    myarray[$((i-1))]=$(echo "${listoffiles}" | sed -n $i'{p;q}')
done

Because you cannot rely on the Bash automatic array instanciation through the myarr=( one two three ) syntax, because it treats the same way all whitespaces (including spaces) it sees within its parentheses. So you have to handle the resulting multiline variable listoffiles kindof manually, what I do in the above script.

echo without the -n option prints a trailing newline at the very end of the variable, but that's fine in our case because find doesn't (you may check this with echo -n "${listoffiles}").

And I use sed to extract the relevant i^th line, with the $i being interpreted by the shell before being given to sed as the first character of its own script.

1 Comment

Bash doesn't treat spaces the same way at all. It just uses the global variable Internal Field Separator ($IFS) to determine which characters are used to separate fields. By default, its value is "spac tab newline" ($' \t\n') but it can be remapped to any value you want. If you change its value to only $'\n', bash will process the output of find line by line and will not count spaces as different fields

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.