If your bash is recent enough:
for a in Array1 Array2; do
declare -n arr="$a"
grep -oFf <(printf '%s\n' "${arr[@]}") file && printf '(in %s)\n' "$a"
done > results
Explanation:
declare -n arr="$a"
declares a nameref, a kind of alias. If executed when the value of a
is Array1
, arr
becomes a synonym of Array1
.
printf '%s\n' "${arr[@]}"
prints each entry in array arr
on a separate line.
<(command)
is a process substitution, the command is run and its output is seen as a file by the environment. In our case the content of the array is considered as a file with one entry per line.
grep -oFf file1 file2
takes the patterns to search in file1
(-f file1
), in our case in the process substitution, considers them as plain text strings, not regular expressions (-F
), and outputs only the matched parts (-o
).
grep
exits with status 0 if a pattern matched, else it exits with a non-zero status. As the 0 exit status is considered as boolean true, the printf '(in %s)\n'
that prints the array name is executed only if grep
found one of the patterns in file
, thanks to the &&
operator (AND).
Demo (output prefixed with -|
):
printf '3\n9\n15\n' > file
Array1=(1 2 3 4 5)
Array2=(6 7 8 9 10)
Array3=(a b c d e)
for a in Array1 Array2 Array3; do
declare -n arr="$a"
grep -oFf <(printf '%s\n' "${arr[@]}") file && printf '(in %s)\n' "$a"
done > results
cat results
-| 3
-| 1
-| 5
-| (in Array1)
-| 9
-| (in Array2)