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

时间:2015-02-17 15:36:38

标签: 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

产生输出

B is 5
B is 

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

谢谢!

1 个答案:

答案 0 :(得分:4)

在第

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变为$0BEGIN块中为空。

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

使用

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

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