awk \
'BEGIN {
# afre = All Fields RegExp
"tr \\\\012 \\| < field-names.txt" | getline afre;
sub(/\|$/, "", afre);
afre = "(^| )("afre")( |$)";
}
$0 ~ afre { print FILENAME; }
{ nextfile; }' **/*.TXT
We take the time once at the start to compute the regex for any one of all the fields looked after,
so that the main "loop" can then run at max throttle.
And as we look only in the first line, after having looked up we use a nextfile unconditionally to switch to the next input file, wether we had a match or not.
So the difference with @anubhava 's solution (that I liked too, and voted up: for my first three bullets, which solution you choose is a matter of taste) are:
^
and $
to match as the first or last fieldNote that depending on the implementation of awk, the $0 ~ afre
may recompile the regexp at each line (because it is a variable, it can… vary, thus awk has to check it has not changed if it wants to cache the compiled version of the regex).
As you run it by shell, you can force it to a fixed regex (more easily optimizable) with an (admitedly less readable):
awk \
'/(^| )('"`tr \\\\012 \| < field-names.txt | sed -e 's/|$//'`"')( |$)/ { print FILENAME; }
{ nextfile; }' \
**/*.TXT