I need to search a pattern in a directory and save the names of the files which contain it in an array.
Searching for pattern:
grep -HR "pattern" . | cut -d: -f1
This prints me all filenames that contain “pattern”.
If I try:
targets=$(grep -HR "pattern" . | cut -d: -f1) length=${#targets[@]} for ((i = 0; i != length; i++)); do echo "target $i: '${targets[i]}'" done
This prints only one element that contains a string with all filnames.
output: target 0: 'file0 file1 .. fileN'
But I need:
output: target 0: 'file0' output: target 1: 'file1' ..... output: target N: 'fileN'
How can I achieve the result without doing a boring split operation on targets?
Answer
You can use:
targets=($(grep -HRl "pattern" .))
Note use of (...)
for array creation in BASH.
Also you can use grep -l
to get only file names in grep
‘s output (as shown in my command).
Above answer (written 7 years ago) made an assumption that output filenames won’t contain special characters like whitespaces or globs. Here is a safe way to read those special filenames into an array: (will work with older bash versions)
while IFS= read -rd ''; do
targets+=("$REPLY")
done < <(grep --null -HRl "pattern" .)
# check content of array
declare -p targets
On BASH 4+ you can use readarray
instead of a loop:
readarray -d '' -t targets < <(grep --null -HRl "pattern" .)
Attribution
Source : Link , Question Author : Luca Davanzo , Answer Author : anubhava