The tool grep
searches files by patterns. This means the pattern is the input and the file is the output. And this means all you can find with grep are files but not patterns.
In order to find those files, which do not contain a matching pattern, you have to invert the search with -v
. This requires two calls.
Example:
$ echo a > xa
$ echo ab > xab
$ echo c > xc
$ { grep -oiE 'a|b' x*; grep -vl -E 'a|b' x*; } | sort -u
xa:a
xab:a
xab:b
xc
In order to find those patterns, which did not match, you have to make your patterns the input and the search result the pattern. The list of matches becomes the pattern and the pattern becomes the data, in which you have to search.
Lets assume this may be the pattern for the files from the preceding example.
$ pattern='a|b|d'
Then this stores the list of matching patterns in an array:
$ found=($(grep -hoiE "$pattern" x* | sort -u))
And this converts the array into the new pattern:
$ new_pattern="$(IFS='|' ; echo "${found[*]}")"
And this converts the original pattern into data:
$ data="${pattern//|/$'\n'}"
Then this is the list of patterns, which did not match:
$ grep -viE "$new_pattern" <<< "$data"
d
*file_name*
denotes multiple files?