awk 文件命令和命令行命令的区别

awk difference between commands from file and from commandline

以下脚本

#! /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

产生输出

B is 5
B is 

我向 awk 发出的命令完全相同,那么为什么变量 B 在第一种情况下被正确解释,而在后者却没有正确解释?

谢谢!

在行

awk 'BEGIN{b=$B;printf("B is %s\n", b)}' sometextfile.txt

字符串文字 'BEGIN{b=$B;printf("B is %s\n", b)}' 被单引号括起来,因此 $B 不会被展开并被视为 awk 代码。在 awk 代码中,B 未初始化,因此 $B 变为 [=16=],在 BEGIN 块中为空。

相比之下,此处文档中的 shell 变量(如您的第一个示例)被扩展,因此 awk.in 最终包含 $B 在 [=34] 中的值=] 脚本。顺便说一句,一旦您尝试使用字段变量(名为 </code>、<code> 等)或整行(名为[=16=]),因为您必须手动解决 awk 字段和 shell 同名变量之间的歧义。

使用

awk -v b="$B" 'BEGIN{ printf("B is %s\n", b) }' sometextfile.txt

使 shell 变量为 awk 代码所知。不要试图将其直接代入 awk 代码;没有必要,您会讨厌以这种方式编写 awk 代码,并且会导致代码注入问题,尤其是当 B 来自不受信任的来源时。