0Pricing
DevOps Bootcamp · レッスン

パターン、範囲、BEGIN/ENDブロック

条件パターンでレコードを絞り込み、BEGINブロックとENDブロックでヘッダーや合計を出力します。

「パターン、範囲、BEGIN/ENDブロック」はCoddyKit上の無料DevOps Bootcampレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはDevOps Bootcamp学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 DevOps Bootcampコースには全4レッスンが含まれています。

awk のパターンとは

awk では、パターンは、指定された入力行に対してアクションブロックを実行するかどうかを制御する条件です。一般的な形式は次のとおりです。

awk 'pattern { action }' file

パターンが現在のレコードに一致すると、アクションが実行されます。アクションを指定しない場合、awk はデフォルトで行全体を出力します。パターンには次の種類があります。

  • 正規表現 — /regex/
  • 関係式 — $3 > 100
  • 複合式 — $1 == "ERROR" && $4 > 500
  • 範囲パターン — /start/,/end/
  • 特殊パターン — BEGIN と END

パターンを理解することは、単なる列の出力ではなく、awk を強力なデータフィルターとして使うための入口です。

行をフィルタリングする正規表現パターン

最も一般的なパターンの種類は、スラッシュで囲んだ正規表現です。awk は各行を正規表現と照合し、一致した場合にのみアクションを実行します。

以下では、/var/log/syslog 形式のファイルをフィルタリングし、ERROR という語を含む行だけを表示します。

#!/usr/bin/env bash
# Simulate a log file and filter ERROR lines
log=$(cat <<'EOF'
2026-06-11 08:01:22 INFO  service started
2026-06-11 08:02:05 ERROR disk quota exceeded on /dev/sda1
2026-06-11 08:02:44 WARN  memory usage at 80%
2026-06-11 08:03:10 ERROR connection timeout to 10.0.0.5
2026-06-11 08:03:55 INFO  backup completed
EOF
)

echo "=== ERROR lines only ==="
echo "$log" | awk '/ERROR/ { print NR": "$0 }'

否定パターンと複合パターン

正規表現パターンの前に ! を付けると、条件を反転できます。つまり、そのパターンを含まない行に一致します。複数の条件は &&(AND)または ||(OR)で組み合わせ、細かく制御できます。

  • !/DEBUG/ — デバッグ行をスキップします
  • $3 > 500 && $5 == "POST" — サイズの大きい POST リクエストです
  • /WARN/ || /ERROR/ — いずれかの重大度です

以下の例では、簡略化したアクセスログを解析し、レスポンスサイズが1000バイトを超える POST リクエストだけを表示します。

#!/usr/bin/env bash
access=$(cat <<'EOF'
10.0.0.1 GET  /api/ping     200  48
10.0.0.2 POST /api/upload   201  2048
10.0.0.3 GET  /api/users    200  512
10.0.0.4 POST /api/data     200  3500
10.0.0.5 POST /api/health   200  60
EOF
)

echo "Large POST requests (>1000 bytes):"
echo "$access" | awk '$2 == "POST" && $5 > 1000 { print $1, $3, "size="$5 }'

範囲パターン: /start/,/end/

範囲パターンは、連続するレコードのまとまりを選択します。/start/ に一致する行から、/end/ に一致する行までを、両端を含めて選択します。構文は次のとおりです。

awk '/start/,/end/ { action }' file

次の動作を理解しておくことが重要です。

  • 範囲は /start/ に一致する最初の行で有効になり、その後に /end/ に一致する最初の行が現れると無効になります。
  • /end/ に一度も一致しない場合、範囲は EOF まで有効なままです。
  • 同じファイル内に重複しない複数の範囲がある場合、それぞれ独立して処理されます。

このため、範囲パターンは設定ファイルの印付きセクション、区切り見出しのあるログ、複数ブロックのレポートから、特定のセクションを抽出するのに適しています。

範囲パターンでセクションを抽出する

複数の名前付きセクションが [section] ヘッダーで区切られているサーバー設定を考えてみましょう。ここでは [database] 内の行だけを取得します。

#!/usr/bin/env bash
config=$(cat <<'EOF'
[server]
host = 0.0.0.0
port = 8080

[database]
host = 127.0.0.1
port = 5432
name = appdb
user = admin

[cache]
host = 127.0.0.1
port = 6379
EOF
)

echo "=== [database] section ==="
echo "$config" | awk '/\[database\]/,/^\[/' \
  | awk 'NR > 1 && !/^\[/ && NF'

BEGIN ブロック

BEGIN ブロックは、入力を読み込む前に1回だけ実行されます。次の用途に適しています。

  • レポートのヘッダーを出力する
  • 変数やカウンターを初期化する
  • フィールド区切り(FS)やその他の組み込み変数を設定する
  • 入力を必要としない単独の awk プログラムを実行する

構文:

awk 'BEGIN { setup } pattern { action }' file

BEGIN で FS を設定する方法は、-F フラグに代わる明確な手段です。特に、区切り文字の処理をスクリプト内に記述する複数ルールのプログラムで役立ちます。

#!/usr/bin/env bash
csv=$(cat <<'EOF'
alice,engineering,95000
bob,marketing,72000
carol,engineering,105000
dave,hr,68000
EOF
)

echo "$csv" | awk 'BEGIN {
  FS = ","
  printf "%-10s %-15s %10s\n", "Name", "Department", "Salary"
  print "--------------------------------------------"
}'

END ブロック

END ブロックは、最後のレコードの処理が終わった後に1回だけ実行されます。次の処理に適した場所です。

  • 処理中に集計した合計、平均、概要を出力する
  • 出力ファイルをフラッシュまたは閉じる
  • 書式付きレポートのフッター行を出力する

メインルールで設定した変数は、END 内でもスコープに残ります。これが累計値を扱える仕組みです。以下の例では、CSV から給与の値を合計し、フッターに合計を出力します。

#!/usr/bin/env bash
csv=$(cat <<'EOF'
alice,engineering,95000
bob,marketing,72000
carol,engineering,105000
dave,hr,68000
EOF
)

echo "$csv" | awk -F',' '
  { total += $3; count++ }
  END { printf "Employees: %d  Total payroll: $%d\n", count, total }
'

BEGIN、ルール、END の組み合わせ

3つすべてのブロックを、ヘッダーを出力し、各レコードを処理し、概要を出力する自己完結型の awk プログラムに組み合わせると、本当の力を発揮します。このパターンは、シェルベースのレポート生成パイプラインの中核です。

以下は、Web リクエストの CSV を読み込み、1行ごとの詳細と、1秒を超えたリクエストの最終件数を出力する完全なレポート生成プログラムです。

#!/usr/bin/env bash
data=$(cat <<'EOF'
/api/ping,0.03
/api/users,1.45
/api/login,0.88
/api/upload,2.10
/api/health,0.02
/api/report,1.73
EOF
)

echo "$data" | awk -F',' '
BEGIN {
  printf "%-20s %10s %s\n", "Endpoint", "Latency(s)", "Status"
  print "--------------------------------------"
}
{
  status = ($2 > 1.0) ? "SLOW" : "OK"
  if (status == "SLOW") slow++
  printf "%-20s %10s %s\n", $1, $2, status
}
END {
  print "--------------------------------------"
  printf "Slow requests: %d / %d\n", slow, NR
}
'

BEGIN で OFS と ORS を設定する

見落とされがちな2つの出力変数も、BEGIN で簡単に設定できます。

  • OFS(出力フィールド区切り) — $1=$1 でレコードを再構築するとき、または print $1, $2 を使うときに、フィールド間へ挿入されます
  • ORS(出力レコード区切り) — 各 print 呼び出しの後に追加されます(デフォルトは \n)

OFS="," を設定すると、文字列連結を使わずに1回の処理で TSV を CSV に再フォーマットできます。ORS を "\n---\n" に変更すると、レコード間に区切り線が自動的に追加されます。

#!/usr/bin/env bash
# Convert whitespace-delimited data to CSV with a header
data=$(cat <<'EOF'
alice   engineering  95000
bob     marketing    72000
carol   engineering  105000
EOF
)

echo "$data" | awk 'BEGIN { OFS=","; print "name,dept,salary" }
{ $1=$1; print }'

実践的な範囲パターン: ログのインシデント期間

範囲パターンは、運用ログの分析で特に力を発揮します。よくある作業の1つは、INCIDENT START や INCIDENT END のような目印となるメッセージで示された、インシデントの開始から終了までのすべてのログ行を抽出することです。

以下の例では、awk がインシデント期間内の行だけを抽出し、その中の ERROR イベントを数えます。範囲パターン、累計用の変数、END の概要出力を組み合わせています。

#!/usr/bin/env bash
log=$(cat <<'EOF'
08:00:01 INFO  Normal operation
08:01:00 INFO  INCIDENT START: disk pressure detected
08:01:05 ERROR write failed on /dev/sda1
08:01:09 ERROR inode table corruption
08:01:14 WARN  remounting read-only
08:01:22 INFO  INCIDENT END: disk replaced
08:02:00 INFO  Normal operation resumed
EOF
)

echo "$log" | awk '
/INCIDENT START/,/INCIDENT END/ {
  print
  if (/ERROR/) errors++
}
END { print "Errors during incident:", errors+0 }
'

範囲内の区切り行をスキップする

デフォルトでは、範囲パターンは /start/ と /end/ に一致する行自体も含みます。これらの区切り行を除外し、その間の内容だけを残すには、否定条件またはフラグ変数でアクションを制御します。

  • 否定を使う方法: /start/,/end/ { if (!/start/ && !/end/) print }
  • フラグを使う方法: /start/ で変数を 1 に、/end/ で 0 に手動設定します

区切り文字列が本文にも現れる可能性がある場合は、フラグを使う方法のほうが堅牢です。

#!/usr/bin/env bash
doc=$(cat <<'EOF'
## preamble
some intro text
## BEGIN_REPORT
row1: alpha 100
row2: beta  200
row3: gamma 150
## END_REPORT
## appendix
EOF
)

echo "$doc" | awk '
/## BEGIN_REPORT/ { capture=1; next }
/## END_REPORT/   { capture=0 }
capture           { print }
'

理解度チェック: BEGIN ブロックの動作

awk で BEGIN ブロックと END ブロックが入力処理とどのように連携するかを確認しましょう。

レッスンのまとめ: パターン、範囲、BEGIN/END

このレッスンでは、awk プログラムで最も強力な3つの構造機能を習得しました。

  • パターン — 正規表現(/ERROR/)、関係式($3 > 1000)、否定(!/DEBUG/)、複合条件(&&、||)によって、明示的な if 文を使わずにアクションを実行するレコードを制御します。
  • 範囲パターン(/start/,/end/) — 連続するレコードのまとまりを選択します。ログのインシデント期間、設定セクション、レポートの一部を抽出するのに最適です。区切り行自体を除外する必要がある場合は、フラグ変数(next + ブール値)を使います。
  • BEGIN ブロック — 入力前に1回実行されます。FS、OFS、ORS の設定、カウンターの初期化、レポートヘッダーの出力に適しています。
  • END ブロック — すべての入力後に1回実行されます。メインルールで蓄積した変数を使って、合計、平均、フッターを出力するのに適しています。

これらの機能を組み合わせることで、一時ファイルや外部ツールを使わず、1つのパイプライン段階だけで、未加工のテキストを取り込み、人間が読みやすい構造化レポートを出力する、完全で自己文書化された awk プログラムを作成できます。

よくある質問

「パターン、範囲、BEGIN/ENDブロック」レッスンは無料ですか?

はい。「パターン、範囲、BEGIN/ENDブロック」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、DevOps Bootcampコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 DevOps Bootcampコースには全4レッスンが含まれています。

「パターン、範囲、BEGIN/ENDブロック」で何を学びますか?

条件パターンでレコードを絞り込み、BEGINブロックとENDブロックでヘッダーや合計を出力します。 ブラウザで直接実行するハンズオンコードでDevOps Bootcampを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

DevOps Bootcampを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのDevOps Bootcampは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「パターン、範囲、BEGIN/ENDブロック」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このDevOps Bootcampレッスンでコードを書いて実行できますか?

はい。すべてのDevOps Bootcampレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. awkのレコード、フィールド、カスタム区切り文字
  2. パターン、範囲、BEGIN/ENDブロック
  3. awk配列とグループ化による集計
  4. awk関数、printfによる書式設定、レポート生成
← DevOps Bootcampに戻る