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?
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).
If you wish to append the output at the end of the file, use >> rather than > as the redirection operator. What this actually does is to start cat and grep concurrently. cat will read from q1. txt and try to write it to its standard output, which is connected to the standard input of grep .
The -n option of the “grep” command is used to print the output of the search string with the line number of the file.
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" .)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With