使用awk命令开始和结束


13

根据awk手册,BEGIN和END不用于匹配输入,而是用于向awk脚本提供启动和清除信息。这是给出的示例:

ls -l | \
awk 'BEGIN { print "Files found:\n" } /\<[a|x].*\.conf$/ { print $9 }'
Files found:
amd.conf
antivir.conf
xcdroast.conf
xinetd.conf

首先,这将打印一个字符串以输出。然后,它检查输入是否存在模式匹配,其中输入以a或x开头,后跟任意字符一次或多次,后跟.conf。对于任何匹配项,将打印第9列。

我们被迫使用从此处开始的事实,是否意味着awk最多只能使用一个包含BEGIN或END的打印功能?如果不是,那为什么我们不能一开始就不使用关键字BEGIN就使用打印功能呢?似乎BEGIN是多​​余的。


仅运行没有BEGIN的命令将回答您的问题,表明它不是多余的,并且您将获得不同的结果。
msb 2014年

Answers:


11

BEGIN不是多余的。如果您未指定BEGINprint则将对输入的每一行执行。

引用手册

一个BEGIN规则仅一次执行时,读取第一个输入记录之前。同样,END读取所有输入后,规则仅执行一次。

$ seq 5 | awk 'BEGIN{print "Hello"}/4/{print}'   # Hello printed once
Hello
4
$ seq 5 | awk '{print "Hello"}/4/{print}'        # Hello printed for each line of input
Hello
Hello
Hello
Hello
4
Hello
$

7

awk处理主体中给定的表达式的行输入,而不是BEGINEND块。在BEGINEND块的情况下awk,分别在输入处理开始之前和输入处理完成之后仅处理一次语句。没有该BEGIN块,不仅您将无法打印一次性信息(例如标题),而且您将无法高效地初始化主体所需的某些变量。另外,仅供参考,一个awk程序可以有多个BEGINEND块。


2

awk仅在匹配的模式之前执行每个块。空模式(仅块)匹配每行。BEGINEND是与文件开头和结尾相匹配的特殊模式(类似于^$在水平方向上的含义)。

如果要在读取文件之前执行某些操作,请使用BEGIN。例如,计数器初始化或其他。END然后可以收集结果。


0

在给定的示例中,我认为该示例已简化,以简化教学,您是正确的,它是多余的。您无需使用即可获得相同的结果BEGIN

1 == NR            { print "Files found:\n" }
/\<[a|x].*\.conf$/ { print $9               }

由于print语句仅限于输入的第一行,因此将产生相同的结果。

话虽如此,BEGINand END块是功能强大的工具。正如其他解决方案所提到的,您可以使用该BEGIN块来初始化变量或其他例程,这些变量或其他例程仅需要执行一次,但是在没有文件要处理时,也可以用于运行Awk命令。一个简单的例子:

BEGIN { print sqrt(12/4) }

您可以在这里看到一个更严重的Awk编程示例,而无需处理任何输入

同样,该END块对于执行计算和汇总所有输入非常有用。如果没有先读取所有数据,通常就无法做到这一点。这里有一个汇总输入的简单示例

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.