Save grep result to array

10,828

With bash-4.4 and above, you'd use:

readarray -d '' -t arr < <(
  find . -type f -print0 | grep -zP 'some pattern')

With older bash versions:

arr=()
while IFS= read -rd '' file; do
  arr+=("$file")
done < <(find . -type f -print0 | grep -zP 'some pattern')

Or (to be compatible to even older versions of bash that didn't have the zsh-style arr+=() syntax):

arr=() i=0
while IFS= read -rd '' file; do
  arr[i++]=$line
done < <(find . -type f | grep -zP 'some pattern')

Your approach has several problems:

  • with -o, grep only prints the parts of the records that match the pattern as opposed to the full record. You don't want it here.
  • find's default newline-delimited output can't be post processed as the newline character is as valid as any in a file path. You need a NUL-delimited output (so -print0 in find and -z in grep to process NUL-delimited records.
  • you also forgot to pass IFS= to read.
  • in bash, and without the lastpipe option, the last part of a pipe line runs in a subshell, so there, you'd only be updating the $arr of that subshell.
Share:
10,828

Related videos on Youtube

user23316192
Author by

user23316192

Updated on September 18, 2022

Comments

  • user23316192
    user23316192 over 1 year

    I want to save all filenames that matches the pattern in bash array.

    My solution does not work. I think the problem is because of pipe usage, but I don't know how to fix it.

    i=0
    find . -type f | grep -oP "some pattern" | while read -r line; do
        arr[$i]=$line;
        let i=i+1;
    done