我在使用我编写的脚本中进行变量赋值时遇到问题awk
。该awk
命令位于函数内部,并且在脚本的其他位置传递给该函数的三个变量。我之前通过awk
使用变量: 来中断命令来完成这项工作awk ... '"$var"' ...
,但显然这是一种相当草率的方法,并且awk
允许通过开关分配变量-v
。
这就是我想做的:
my_function() {
command1 \
| command2 \
| awk -v var1="$1" -v var2="$2" -v var3="$3" '{
FS="[ ,\"]+"}/var1=/{
for ( i=2; i<NF; i++) {
if ( var2 ){
var3; next;
}
}
}
{
fname=$0
}'
}
...
my_function "$firstArg" "$secondArg" "$thirdArg"
根据 using 的输出set -x
,我可以看到变量赋值在 awk 命令的开头正确进行,但该awk
命令只是返回任何内容,而不是按这种方式执行awk ... '"$var"' ...
,这确实可以正常工作。
我觉得我在这里错过了一些东西。
答案1
看起来这可能就是您想要做的事情:
my_function() {
command1 |
command2 |
awk -v var1="$1" -v var2="$2" -v var3="$3" '
BEGIN { FS="[ ,\"]+" }
$0 ~ (var1"=") {
for ( i=2; i<NF; i++) {
if ( $0 ~ var2 ) { # maybe just "if (var2)", depends on context
var3 # NOTE: this line does nothing
next
}
}
}
{ fname=$0 } # NOTE: this is populating a variable thats never used.
'
}
...
my_function "$firstArg" "$secondArg" "$thirdArg"
是的,awk ... '"$var"' ...
太可怕了。考虑:
$ var=$(printf 'a\nb')
$ echo "$var"
a
b
明显的、理想的输出:
$ awk -v foo="$var" 'BEGIN{print foo}'
a
b
模糊的、不需要的输出:
$ awk 'BEGIN{print '"$var"'}'
$ awk 'BEGIN{print "'"$var"'"}'
awk: cmd. line:1: BEGIN{print "a
awk: cmd. line:1: ^ unterminated string
awk: cmd. line:1: BEGIN{print "a
awk: cmd. line:1: ^ syntax error
$
看如何在 awk 脚本中使用 shell 变量有关在 awk 脚本中使用 shell 变量值的不同方法的完整讨论。-v
根据 shell 变量的内容,使用可能是错误的方法,并且使用ENVIRON[]
或ARGV[]
可能会更好。
我更改{FS="[ ,\"]+"}
为,BEGIN{FS="[ ,\"]+"}
因为您在问题中的脚本中执行此操作的方式是为每个输入行设置一次,但是在该行已经被分割之后,因此您设置的 FS 将不会应用于第一个输入行并且您所做的工作是每行设置一次而不是总共设置一次。看看区别:
$ printf 'a,b\nc,d\n' | awk '{FS=","} {print $1}'
a,b
c
$ printf 'a,b\nc,d\n' | awk 'BEGIN{FS=","} {print $1}'
a
c
目前还不清楚你希望var3;
做什么,但它会做什么——什么也没有。
请注意我如何缩进和使用换行,以便代码的结构反映程序的控制流。您问题中的代码中的缩进等不会做到这一点,因此会混淆您的代码 - 尝试按照我在未来上面显示的样式构建您的代码,gawk -o-
如果您不确定如何,请运行它以进行漂亮的打印构建它。