This will work (but you have to be careful what you use for an argument):
st() { awk "FNR==2 {if (/$1/) print FILENAME; nextfile}" ./*; }
The danger here is that $1
becomes part of the code and, if it includes awk-active characters, could do surprising things.
This is a bit safer:
st() { awk -v c="$1" 'FNR==2 {if ($0 ~ c) print FILENAME; nextfile}' ./*; }
Here, we pass into awk a variable c
that has the contents of $1
. awk will know to treat c
as a variable, not as code.
This is the same as the above but it simplifies the logic:
st() { awk -v c="$1" 'FNR==2 && $0~c {print FILENAME; nextfile}' ./*; }
How it works
-v c="$1"
This defines awk variable c
. This is the most reliable to pass information from the shell to awk
.
FNR==2 && $0~c {print FILENAME; nextfile}
This applies two conditions and'd together before the print
/nextfile
statement is executed. The first requires that this be the second line. The second requires that this line match c
.
The shell and quoting
The difference between single and double quotes is easily demonstrated at the command line. Try:
$ var="Hello"
$ echo '$var'
$var
$ echo "$var"
Hello
As shown above, the shell treats the contents of single-quotes literally. It makes no changes to what is inside single-quotes. By contrast, the shell will process the contents of double-quotes, doing variable substitution (shown above), as well as command substitution and arithmetic expansion. To demonstrate the latter two:
$ echo '$var $(date) $((2*3))'
$var $(date) $((2*3))
$ echo "$var $(date) $((2*3))"
Hello Wed Nov 19 14:15:44 PST 2014 6