如何在awk脚本中使用shellvariables?

我发现了一些将外部variables传递给awk脚本的方法,但是我对'"感到困惑。

首先,我尝试了一个shell脚本:

 $ v=123test $ echo $v 123test $ echo "$v" 123test 

然后尝试awk:

 $ awk 'BEGIN{print "'$v'"}' $ 123test $ awk 'BEGIN{print '"$v"'}' $ 123 

为什么区别?

最后我尝试了这个:

 $ awk 'BEGIN{print " '$v' "}' $ 123test $ awk 'BEGIN{print ' "$v" '}' awk: cmd. line:1: BEGIN{print awk: cmd. line:1: ^ unexpected newline or end of string 

我对此感到困惑。

将shellvariables转换为awk可能有几种方式。 有些人比别人好。


这是做到这一点的最好方法。 它使用-v选项:(PS在-v之后使用一个空格,否则它的可移植性会降低,例如, awk -v var= not awk -vvar

 variable="line one\nline two" awk -v var="$variable" 'BEGIN {print var}' line one line two 

这应该与大多数awk兼容,variables也可以在BEGIN块中使用:


你可以在awk代码中使用一个variables,但是它很杂乱,很难阅读,正如Charles Duffy指出的那样,这个版本也可能是代码注入的牺牲品。 如果有人把不好的东西添加到variables中,它将作为awk代码的一部分执行,所以不要使用。

 variable="line one\nline two" awk 'BEGIN {print "'"$variable"'"}' line one line two 

这是一个代码注入的例子:

 variable='line one\nline two" ; for (i=1;i<=1000;++i) print i"' awk 'BEGIN {print "'"$variable"'"}' line one line two 1 2 3 . . 1000 

你可以通过这种方式添加很多awk命令。 即使使用非有效的命令使其崩溃。


在这里我们得到了awk代码之后的variables。 只要您不需要BEGIN块中的variables,这样就可以正常工作:

 variable="line one\nline two" echo "input data" | awk '{print var}' var="$variable" or awk '{print var}' var="$variable" file 

使用这里的string也可以将variables添加到awk

 awk '{print $0}' <<< "$variable" test 

这是一样的:

 echo "$variable" | awk '{print $0}' 

双引号variables"$variable"总是好的
如果没有,多行将被添加为一个长的单行。

例:

 var="Line one This is line two" echo $var Line one This is line two echo "$var" Line one This is line two 

其他错误,你可以得到没有双引号:

 variable="line one\nline two" awk -v var=$variable 'BEGIN {print var}' awk: cmd. line:1: one\nline awk: cmd. line:1: ^ backslash not last character on line awk: cmd. line:1: one\nline awk: cmd. line:1: ^ syntax error 

用单引号,它不会扩大variables的值:

 awk -v var='$variable' 'BEGIN {print var}' $variable 

正如TrueY写的,你可以使用ENVIRON来打印Environmental Variablesvariables在运行AWK之前设置一个variables,你可以这样打印出来:

 X=MyVar awk 'BEGIN{print ENVIRON["X"],ENVIRON["SHELL"]}' MyVar /bin/bash 

似乎没有提到老式的ENVIRON awk内置哈希。 其用法的一个例子:

 $ X=Solaris awk 'BEGIN{print ENVIRON["X"], ENVIRON["TERM"]}' Solaris rxvt 

取决于如何在shellvariables中处理反斜杠( avar是awkvariables, svar是shellvariables):

 awk -v avar="$svar" '... avar ...' file awk 'BEGIN{avar=ARGV[1];ARGV[1]=""}... avar ...' "$svar" file 

有关详细信息和其他选项,请参阅http://cfajohnson.com/shell/cus-faq-2.html#Q24 。 上面的第一种方法几乎总是您最好的select,并且具有最明显的语义。

您可以在命令行选项 -v中input环境variables( "${v}" )的variables名称( v )和值( = ):

 % awk -vv="${v}" 'BEGIN { print v }' 123test 

或者使之更清楚(很less有v ):

 % environment_variable=123test % awk -vawk_variable="${environment_variable}" 'BEGIN { print awk_variable }' 123test 

我不得不在日志文件的行的开头插入date,它的完成如下:

 DATE=$(date +"%Y-%m-%d") awk '{ print "'"$DATE"'", $0; }' /path_to_log_file/log_file.log 

它可以redirect到另一个文件来保存

你可以使用ARGV:

 v=123test awk 'BEGIN {print ARGV[1]}' "$v" 

请注意,如果您要继续进入体内,您需要调整ARGC:

 awk 'BEGIN {ARGC--} {print ARGV[2], $0}' file "$v"