Shell 如何预先构造awk语句以在命令行上传递给awk?
我有一个shell脚本,它将awk程序构造为字符串,然后将该字符串传递给awk。这是因为我想在awk程序中使用shell变量的值 我的代码如下所示:Shell 如何预先构造awk语句以在命令行上传递给awk?,shell,cygwin,awk,Shell,Cygwin,Awk,我有一个shell脚本,它将awk程序构造为字符串,然后将该字符串传递给awk。这是因为我想在awk程序中使用shell变量的值 我的代码如下所示: awk_prog="'{if (\$4~/$shell_var/) print \$1,\$2}'" echo $awk_prog awk $awk_prog $FILENAME 但是,当我将字符串传递给awk时,总是会出现以下错误: '{if ($4~/regex/) print $1,$2}' awk: '{if awk: ^ invalid
awk_prog="'{if (\$4~/$shell_var/) print \$1,\$2}'"
echo $awk_prog
awk $awk_prog $FILENAME
但是,当我将字符串传递给awk时,总是会出现以下错误:
'{if ($4~/regex/) print $1,$2}'
awk: '{if
awk: ^ invalid char ''' in expression
那个错误消息是什么意思?我试过-F:开关,但没用。我怎样才能解决这个问题
谢谢。这是由壳牌公司的报价引起的。以下工作将起作用:
awk_prog="{ if (\$4 ~ /$shell_var/) print \$1, \$2 }"
echo "$awk_prog"
awk "$awk_prog" $FILENAME
从命令行运行awk'{print}'foo
时,shell解释并删除程序周围的引号,因此awk接收两个参数-第一个是程序文本,第二个是文件名foo
。您的示例向awk发送程序文本“{if…}”
,就awk而言,这是无效的语法。外部引号不应出现
在我上面给出的代码片段中,shell使用
awk_prog=
行中的引号将字符串的内容分组为单个值,然后将其分配给变量awk_prog
。当它执行awk“$awk_prog”…
行时,您必须引用$awk_prog
的扩展,以便awk将程序文本作为单个参数接收。有另一种方法将shell变量放入awk中--使用awk的-v
选项:
awk -v pattern="$shell_var" '$4 ~ pattern {print $1, $2}' "$FILENAME"
如果有多个变量要传递给awk,请多次使用-v
如果您确实想将awk程序保存在shell变量中,请使用printf
构建它:
awk_script="$( printf '$4 ~ /%s/ {print $1, $2}' "$shell_var" )"
awk "$awk_script" "$FILENAME"
注意printf命令中使用引号:模板周围使用单引号来保护您希望awk解释的美元符号,shell变量使用双引号。另一个(我认为)解决方案(更简单)解决了您凭直觉试图做的事情,就是简单地使用eval。您希望shell的行为就像您按字面意思键入:
awk '{if ($4~/foo/) print $1,$2}' path
awk'{if($4~/foo/)打印$1,$2}'路径
(其中foo和path是$shell_var和$FILENAME的文本内容)。要做到这一点,只需在最后一行的前面加上一个eval(可能还加上引号,但在本例中不需要),这样你的最后一行就是:
eval "awk $awk_prog $FILENAME"
评估“awk$awk_prog$FILENAME”