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?

1

1 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" .) 
5

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy