来自文件和命令行的命令之间的awk差异

来自文件和命令行的命令之间的awk差异,awk,Awk,下面的脚本 #! /bin/bash B=5 #FILE INPUT cat <<EOF > awk.in BEGIN{b=$B;printf("B is %s\n", b)} EOF awk -f awk.in sometextfile.txt #COMMANDLINE INPUT awk 'BEGIN{b=$B;printf("B is %s\n", b)}' sometextfile.txt 我向awk发出的命令是完全相同的,那么为什么变量B在第一种情况下解释正确

下面的脚本

#! /bin/bash

B=5

#FILE INPUT
cat <<EOF > awk.in
BEGIN{b=$B;printf("B is %s\n", b)}
EOF
awk -f awk.in sometextfile.txt

#COMMANDLINE INPUT
awk 'BEGIN{b=$B;printf("B is %s\n", b)}' sometextfile.txt
我向awk发出的命令是完全相同的,那么为什么变量B在第一种情况下解释正确,而在后一种情况下解释不正确呢

谢谢

排队

awk 'BEGIN{b=$B;printf("B is %s\n", b)}' sometextfile.txt
字符串literal
'BEGIN{b=$b;printf(“b是%s\n,b)}”
被单独引用,因此
$b
不会展开并被视为awk代码。在awk代码中,
B
未初始化,因此
$B
变为
$0
,在
开始
块中为空

相反,此处文档中的shell变量(如您的第一个示例中)是展开的,因此
awk.In
最终包含了
$B
在shell脚本中的值。顺便说一句,当您尝试使用字段变量(名为
$1
$2
,等等)或整行(名为
$0
)时,编写awk代码会非常痛苦,因为您必须手动解决awk字段和同名shell变量之间的歧义

使用

使外壳变量为awk代码所知。不要试图将其直接替换为awk代码;这是不必要的,你会讨厌用这种方式编写awk代码,并且会导致代码注入问题,特别是当
B
来自不可信的源代码时

awk 'BEGIN{b=$B;printf("B is %s\n", b)}' sometextfile.txt
字符串literal
'BEGIN{b=$b;printf(“b是%s\n,b)}”
被单独引用,因此
$b
不会展开并被视为awk代码。在awk代码中,
B
未初始化,因此
$B
变为
$0
,在
开始
块中为空

相反,此处文档中的shell变量(如您的第一个示例中)是展开的,因此
awk.In
最终包含了
$B
在shell脚本中的值。顺便说一句,当您尝试使用字段变量(名为
$1
$2
,等等)或整行(名为
$0
)时,编写awk代码会非常痛苦,因为您必须手动解决awk字段和同名shell变量之间的歧义

使用


使外壳变量为awk代码所知。不要试图将其直接替换为awk代码;这是不必要的,你会讨厌用这种方式编写awk代码,这会导致代码注入问题,特别是当
B
来自不可信的源代码时。

可能值得一提的是,heredocs中的变量是扩展的。@EtanReisner你可能是对的,所以我添加了一点。可能值得明确提及的是,heredocs中的变量是展开的。@EtanReisner您可能是对的,所以我添加了一点。
awk -v b="$B" 'BEGIN{ printf("B is %s\n", b) }' sometextfile.txt