Pass shell variable as a /pattern/ to awk
Use awk's ~
operator, and you don't need to provide a literal regex on the right-hand side:
function _process () {
awk -v l="$line" -v pattern="$1" '
$0 ~ pattern {p=1}
END {if(p) print l >> "outfile.txt"}
'
}
Although this would be more efficient (don't have to read the whole file)
function _process () {
grep -q "$1" && echo "$line"
}
Depending on the pattern, may want grep -Eq "$1"
awk -v pattern="$1" '$0 ~ pattern'
Has an issue in that awk
expands the ANSI C escape sequences (like \n
for newline, \f
for form feed, \\
for backslash and so on) in $1
. So it becomes an issue if $1
contains backslash characters which is common in regular expressions (with GNU awk
4.2 or above, values that start with @/
and end in /
, are also a problem). Another approach that doesn't suffer from that issue is to write it:
PATTERN=$1 awk '$0 ~ ENVIRON["PATTERN"]'
How bad it's going to be will depend on the awk
implementation.
$ nawk -v 'a=\.' 'BEGIN {print a}'
.
$ mawk -v 'a=\.' 'BEGIN {print a}'
\.
$ gawk -v 'a=\.' 'BEGIN {print a}'
gawk: warning: escape sequence `\.' treated as plain `.'
.
$ gawk5.0.1 -v 'a=@/foo/' BEGIN {print a}'
foo
All awk
s work the same for valid escape sequences though:
$ a='\\-\b' awk 'BEGIN {print ENVIRON["a"]}' | od -tc
0000000 \ \ - \ b \n
0000006
(content of $a
passed as-is)
$ awk -v a='\\-\b' 'BEGIN {print a}' | od -tc
0000000 \ - \b \n
0000004
(\\
changed to \
and \b
changed to a backspace character).
Try something like:
awk -v l="$line" -v search="$pattern" 'BEGIN {p=0}; { if ( match( $0, search )) {p=1}}; END{ if(p) print l >> "outfile.txt" }'