awkコマンドを使用したBEGINおよびEND


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で始まり、その後に任意の文字が1回以上続き、その後に.confが続きます。一致した場合、9列目が出力されます。

ここでbeginを使用せざるを得ないという事実は、それはawkがBEGINまたはENDを含む最大1つの印刷関数しか使用できないことを意味しますか?そうでない場合、キーワードBEGINなしで最初にprint関数を使用できないのはなぜですか?BEGINは不要なようです。


BEGINなしでコマンドを実行するだけで質問に答えることができます。それは不必要ではなく、別の結果が得られることを示しています。
msb 2014年

回答:


11

BEGIN余計ではありません。指定しない場合BEGIN、次にprint入力のライン毎に実行されます。

マニュアルからの引用:

BEGIN最初の入力レコードが読み込まれる前に、ルールは、一度だけ実行されます。同様に、ENDすべての入力が読み取られた後、ルールは1回だけ実行されます。

$ 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ます。BEGINおよびENDブロックの場合、awk入力の処理が開始される前と入力の処理がそれぞれ完了した後に、ステートメントを1回だけ処理します。せずにBEGINブロックだけでなく、あなたが効率的に体内で必要とされるいくつかの変数を初期化することができないであろう、そのようなヘッダとしてワンタイム情報を印刷することができません。また、参考までに、awkプログラムには複数のBEGINENDブロックを含めることができます。


2

awk前のパターンが一致した場合にのみ、すべてのブロックを実行します。空のパターン(ブロックのみ)はすべての行に一致します。BEGINそしてENDファイルの先頭と最後(の意味に類似一致する特殊なパターンであり、^かつ$、水平方向には)。

ファイルを読み取る前に何かを実行したい場合は、を使用します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ブロックは計算を実行し、すべての入力を要約するのに非常に役立ちます。これは、最初にすべてのデータを読み取らなければ(通常)実行できません。入力を要約する簡単な例はここにあります

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.