awk向脚本传递参数(二)


命令行参数的一个重要限制是它们在BEGIN过程中是不可用的。也就是说,直到首行输入完成以后它们才可用。为什么?这是一个容易混乱的部分。从命令行传递的参数就好像文件名一样被处理。赋值操作知道这个变量(如果它是一个文件名)被求值时才进行。

参阅下面的脚本,该脚本将变量n设置为一个命令行参数。

awk ' BEGIN { print n }
if (n == 1) print "Reading the first file"
if (n == 2) print "Reading the second file"
}' n=1 test n=2 test2

这里有4个命令行参数: "n=1 "、"test" 、"n=2 "和"test2"。如果你现在还记着BEGIN过程即"在处理输入之前所要做的",你将会理解为什么在BEGIN过程中的参数n返回值为空,因此print语句将打印一个空行。如果第一个参数是一个文件而不是一个变量赋值。该文件会知道BEGIN过程执行后才被打开。

第一个参数为变量n赋初值1 ,第二个参数提供了文件名。因此,对于test中的每一行,条件"n==1 "都为真。在读完test中的所有行之后,计算第三个参数,并将n赋值为2 。最后,第四个参数提供了第二个文件名。这时在主过程中的条件"n==2"为真。

以这种方法对参数求值的后果是不能用BEGIN过程测试或检验命令行提供的参数。只有当输入一行后它们才能够使用。要了解这种局限性,可以通过编写规则"NR==1"并使用它的过程来检验参数的赋值。另一个方法是在调用awk之前在shell脚本中测试命令行参数。

POSIX awk提供了一个解决这个问题的方法,即在任何输入被读入前定义参数。用-v选项指定要在执行BEGIN 过程之前得到变量赋值(也就是,在读入第一个输入行之前)。-v选项必须在一个命令行脚本前说明。例如:下列命令使用-v选项为多行记录设置记录分隔符。

$ awk -F'\n" -v RS="" '{ print }' phones.block

每个传递给程序的变量赋值都需要一个不同的-v选项。

和C程序语言类似,awk也提供系统变量ARGC和ARGV。因为这需要了解数组,我们将在第八幸"条件、循环和数组"中讨论这些特点。

相关内容