如何在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 Variables
variables在运行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"