次のコマンドは同じ答えを生成します。
tail -n 1 ~/watchip.sh.csv | awk 'BEGIN { FS = "," } ; { print $1 }'
tail -n 1 ~/watchip.sh.csv | awk '{ FS = "," } ; { print $1 }'
編集:この質問を投稿した後、上記の2つのコマンドが同じ答えを生成するという私の主張が間違っていることがわかりました。少なくとも一般的にはそうではありません。したがって、上記のコマンドは
BEGIN
ステートメントが必要な場合の例のようです。混乱させて申し訳ありません。
私は経験豊富なawk
ユーザーではありませんが、この製品を使用して文書を読んでより良い使い方をするよう努めています。しかし、私がBEGINとENDで読んだことはすべてあいまいです(私にとってはほとんど理解されていません)。それはおそらく、私がawk
非常に限られた状況でのみ使用したからです。
BEGIN文がいつであるかを簡単に説明できる人はいますか?必須存在するawk
?
答え1
BEGIN
andEND
句は、実際に何かをしたいときに主に使用されます。awk
今後そして後ろにファイルの実際の処理は別々に行われます。したがって、このロジックを使用すると、そのロジックのステートメント/アクションは、指定された入力ファイルに対して一度だけ実行されます。
通常、どのような種類のタスクが実行されますかBEGIN
?
行入力を分割するために使用される特殊変数(たとえば、入力フィールドと出力フィールドの区切り文字)を初期化します
FS
。OFS
常に構文を使用してこれらの特殊変数を定義したり、-v FS=
正規表現演算子で定義したりできますが、そうすればはるかに-F','
読みやすくなります。あなたの例で判断すると、入力ファイルの各行の変数を初期化するため、{ FS="," }
本文でこれを定義する必要があるのはやや重複します。awk
たとえば、行にn行が含まれていると、初期化がn回発生します。echo "1,2,3" | awk 'BEGIN {FS=OFS=","} {print $1}'
スクリプト本文で生成された出力のカスタムヘッダー行を定義します
awk
。たとえば、前の例では、最初の列の値を印刷していることを示すヘッダーを印刷したいと思いました。echo "1,2,3" | awk 'BEGIN {FS=OFS=","; print "First column values only"} {print $1}'
(オプション - 読みやすくするため) - プログラム本文内で使用される変数を初期化することもできます。推奨されませんが、変数の初期化を動的に処理するため、変数の状態を理解するのに
awk
役立ちます。BEGIN
echo "1,2,3" | awk 'BEGIN {FS=OFS=","; counter = 0; } $1 == "1" { counter++ }'
通常、どのような種類のタスクが実行されますかEND
?
コマンド本文で処理された行数を追跡します
awk
。一般的な慣用語は、ファイルの行数を追跡することです。各行が処理されるたびに増加する実行カウンタである特殊awk
変数を使用します。NR
つまり、最初の行変数の値は 1 になってから増加します。しかし、この場合、ファイルの総行数をどのように印刷できますか?print NR
ファイルの処理中に現在行番号を印刷するため、ファイル本文ではこれを行う方法はありません。awk
たとえば、以下の最初のスニペットは機能しません。それで、END
これはその中のステートメントが次のようなときに起こります。後ろにファイル処理が完了しました。したがって、同じ方法で印刷すると、保存されたEND
最後の値が印刷されます。NR
printf '1\n2\n\3' | awk '{print "total="NR}' total=1 total=2 total=3 printf '1\n2\n\3' | awk 'END{print "total="NR}' total=3
ヘッダ情報を印刷するセクションと同様に、
BEGIN
この時点ですべてのファイル処理が完了するため、文字列と情報をまとめて印刷できます。
この文書効果的なAWKプログラミングツールをよりよく理解するのに最適なリソースです。
答え2
「効果的なAWKプログラミング」は私にとって非常に役立ちました。
awkはパターンとアクションで構成されるルールと連携し、どちらも省略できますが、どちらも省略することはできません。 BEGINとENDはパターンで、{...}は演算です。パターンが存在しない場合、またはパターンが一致しない場合、操作が実行されます。
awk 'BEGIN {FS=OFS=","} {print $1}'
^pattern + ^action ^ action without pattern
awk '{ FS = "," } ; { print $1 }'
^action without pattern ^ another action without pattern
一般的なawkプログラムでは:
- BEGIN{...}はレコードの前に実行されるため、ここで必要なものをすべて初期化できます。
- 各レコードはメインループであるパターン{...}を実行します。
- END{...}は最後のレコード以降に実行されます。メインループが完了し、すべてのデータがあなたの手にあるので、あなたが望むものは何でもすることができます。