Q1BEGIN { ... }の中身はいつ実行されますか?
awk — 集計とレポート
awkのBEGIN { } とEND { } が走る順番、s += $1で1列目を累計して合計を出す書き方、NRや { c++ } で件数を数える集計レポートの作り方を、図解とブラウザ端末で確認します。
処理の前後に走る — BEGIN と END
awkは各行を順に読みながら処理しますが、その前後に一度だけ実行したい処理をBEGIN { ... }とEND { ... }に書けます。BEGINは最初の行を読む前に 1 回、ENDはすべての行を読み終えた後に 1 回だけ走ります。見出しを先に出したり、集計結果を最後にまとめて出したりするときに使います。
BEGINは処理前に 1 回、本体は行ごとに、ENDは処理後に 1 回走ります。| 書き方 | 意味 |
|---|---|
BEGIN { ... } | 最初の行を読む前に 1 回だけ実行する |
{ ... } | 1 行ずつ繰り返し実行する本体 |
END { ... } | すべての行を読んだ後に 1 回だけ実行する |
s += $1 | 1 列目の値を変数sに足し続けて累計する |
NR | ここまでに読んだ行数(最終的に総行数) |
{ c++ } END { print c } | 行ごとにcを増やし、件数を最後に出す |
printf 'start\nmiddle\nend\n' > lines.txt # 3 行の素材を作成
awk 'BEGIN { print "--- report ---" } { print $0 } END { print "rows:", NR }' lines.txt
# 先頭に見出し、最後に rows: 3 が付く
Linux console
0 / 3 実行済み
Loading Linux Terminal...
合計と件数 — s += $1 と NR
awkでは変数を宣言なしで使え、数値はそのまま足し算できます。本体に{ s += $1 }と書くと、各行の 1 列目の値が変数sに足され続け、END { print s }で最後に合計が出ます。件数は読んだ行数を表すNRをそのままENDで出すか、{ c++ }でカウンタを増やしてEND { print c }で出します。これで売上の合計や件数といった集計レポートが作れます。
s += $1が行ごとに 1 列目を足し、ENDで合計 60 を出力します。printf '120 mon\n80 tue\n200 wed\n' > sales.txt # 数値付き 3 行を作成
awk '{ s += $1 } END { print "total:", s }' sales.txt # total: 400
awk 'END { print "days:", NR }' sales.txt # days: 3
Linux console
0 / 4 実行済み
Loading Linux Terminal...
件数をカウンタで数える — { c++ } END { print c }
NRは全行を数えますが、条件に合う行だけを数えたいときは本体でカウンタを使います。{ c++ }は読んだ行ごとに変数cを 1 ずつ増やし、END { print c }でその件数を出します。/pat/{ c++ }のようにパターンを付ければ、特定の文字列を含む行だけを数えられます。
/pass/{ c++ }は一致行だけでcを増やし、ENDで件数 2 を出力します。| 書き方 | 意味 |
|---|---|
{ c++ } | 読んだ行ごとに変数cを 1 増やす |
/pattern/{ c++ } | patternを含む行だけでcを増やす |
END { print c } | 最後に件数cを 1 回出力する |
printf 'ok pay\nng pay\nok ship\n' > log.txt # 状態付き 3 行を作成
awk '/ok/{ c++ } END { print "ok count:", c }' log.txt # ok を含む行を数える -> 2
Linux console
0 / 4 実行済み
Loading Linux Terminal...
QUIZ
理解度チェック
まずは1問ずつ答えてみましょう。
Q2awk '{ s += $1 } END { print s }' fは何を表示しますか?
Q3ENDブロックでNRを表示すると何が出ますか?