はじめに
awkはテキスト処理に特化した強力なコマンドで、シンプルなscriptから高度なデータ解析まで幅広く活用できます。
本記事ではawkコマンドの基本構造とスクリプト実行の仕組みを軸に、初学者がつまずきやすいポイントを整理します。
参考: GNU awk
awkコマンドの基本構造とスクリプト実行の仕組み
ファイル作成
cat << 'EOF' > input.txt
apple 100
banana 200
orange 150
EOF
実行コマンド
awk '{print $1, $2}' input.txt
実行結果
apple 100
banana 200
orange 150
実行コマンド
awk '$2 > 150 {print $1}' input.txt
実行結果
banana
実行コマンド
awk '{sum += $2} END {print sum}' input.txt
実行結果
450
仕組み
| 要素 | 内容 |
|---|---|
| パターン | 条件式(例: $2 > 150) |
| アクション | 実行処理(例: {print $1}) |
| フィールド | $1, $2 など列データを参照 |
| ENDブロック | 全行処理後に実行される処理 |
| スクリプト実行 | コマンド内またはファイルで実行可能 |
解説
awkは「パターン+アクション」で各行を処理するストリーム指向ツールです。簡単なワンライナーからスクリプト化まで柔軟に対応できます。
awkスクリプトファイルを保存・実行する2つの基本手法
ファイル作成
cat << 'EOF' > input.txt
apple
banana
cherry
EOF
ファイル作成
cat << 'EOF' > script.awk
BEGIN { print "=== awk script start ===" }
{ print NR ":" $0 }
END { print "=== awk script end ===" }
EOF
実行コマンド
awk -f script.awk input.txt
実行結果
=== awk script start ===
1:apple
2:banana
3:cherry
=== awk script end ===
実行コマンド
sed -i '1i #!/usr/bin/awk -f' script.awk
chmod +x script.awk
./script.awk input.txt
実行結果
=== awk script start ===
1:apple
2:banana
3:cherry
=== awk script end ===
仕組み
| 手法 | 実行方法 | 仕組み |
|---|---|---|
| -fオプション | awk -f script.awk | awkコマンドに外部スクリプトを読み込ませる |
| 実行ファイル化 | ./script.awk | shebangでawkを指定し、スクリプト自体を直接実行 |
解説
awk scriptは外部ファイルとして分離することで再利用性が高まり、用途に応じて実行方法を選べます。シンプルな処理は-f、ツール化するなら実行ファイル化が便利です。
BEGINブロックを活用したスクリプトの初期化処理
ファイル作成
cat << 'EOF' > input.txt
apple 100
banana 200
orange 150
EOF
実行コマンド
awk 'BEGIN { sum=0; print "=== 集計開始 ===" } { sum += $2 } END { print "合計:", sum }' input.txt
実行結果
=== 集計開始 ===
合計: 450
仕組み
| ブロック | タイミング | 処理内容 |
|---|---|---|
| BEGIN | 読み込み前 | 変数初期化、ヘッダー出力 |
| 本体 | 各行処理 | 2列目の数値を加算 |
| END | 読み込み後 | 合計値の出力 |
解説
BEGINブロックは入力処理前に一度だけ実行され、初期化に最適です。
awkスクリプトでは集計処理の前準備として頻繁に使われます。
コマンドライン引数をスクリプト内で変数として扱う方法
ファイル作成
cat << 'EOF' > script.awk
BEGIN {
arg1 = ARGV[1]
arg2 = ARGV[2]
print "arg1 =", arg1
print "arg2 =", arg2
# awkが通常ファイルと認識しないよう削除
delete ARGV[1]
delete ARGV[2]
}
{
print "input:", $0
}
EOF
実行コマンド
echo "hello world" | awk -f script.awk foo bar
実行結果
arg1 = foo
arg2 = bar
input: hello world
仕組み
| 要素 | 内容 |
|---|---|
| ARGV | コマンドライン引数の配列 |
| ARGV[0] | awkコマンド自身 |
| ARGV[1..] | ユーザー指定の引数 |
| delete | awkが入力ファイルとして扱うのを防ぐ |
| BEGIN | 入力処理前に実行されるブロック |
解説
ARGVを使うことでawkスクリプト内でも引数を扱える。
不要な引数はdeleteしないとファイルとして処理される点が重要。
外部スクリプトファイルにおける正規表現の効率的な記述法
ファイル作成
cat << 'EOF' > input.txt
apple 100
banana 200
apricot 150
grape 300
EOF
ファイル作成
cat << 'EOF' > script.awk
/^(a|b)/ {
if ($2 ~ /^[0-9]+$/) {
sum += $2
print $1, $2
}
}
END {
print "TOTAL:", sum
}
EOF
実行コマンド
awk -f script.awk input.txt
実行結果
apple 100
banana 200
apricot 150
TOTAL: 450
仕組み
| 要素 | 内容 |
|---|---|
| 正規表現 `/^(a|b)/` | a または b で始まる行を対象 |
| 数値判定 /^[0-9]+$/ | 数値のみのフィールドを検証 |
| アクション {...} | 条件一致時の処理を記述 |
| sum += $2 | 数値を累積 |
| END | 最終処理で合計出力 |
解説
正規表現をパターン部に直接書くことで分岐を減らし効率化できます。awkは条件と処理を一体化できるため、外部スクリプトでも簡潔に高速処理が可能です。
組み込み変数(NR, NF, FS)を駆使したレコード制御
ファイル作成
cat << 'EOF' > input.txt
apple,fruit,100
carrot,vegetable,80
banana,fruit,120
EOF
ファイル作成
cat << 'EOF' > script_all.sh
#!/bin/bash
awk -F',' '{ print "NR=" NR, "NF=" NF, "1=" $1, "2=" $2, "3=" $3 }' input.txt
EOF
ファイル作成
cat << 'EOF' > script_line2.sh
#!/bin/bash
awk -F',' 'NR==2 { print "2行目:", $1, $2, $3 }' input.txt
EOF
ファイル作成
cat << 'EOF' > script_fruit.sh
#!/bin/bash
awk -F',' '$2=="fruit" { print "果物:", $1, $3 }' input.txt
EOF
実行コマンド
chmod +x script_all.sh script_line2.sh script_fruit.sh
実行コマンド
./script_all.sh
実行結果
NR=1 NF=3 1=apple 2=fruit 3=100
NR=2 NF=3 1=carrot 2=vegetable 3=80
NR=3 NF=3 1=banana 2=fruit 3=120
実行コマンド
./script_line2.sh
実行結果
2行目: carrot vegetable 80
実行コマンド
./script_fruit.sh
実行結果
果物: apple 100
果物: banana 120
仕組み
| 変数 | 意味 | 役割 |
|---|---|---|
| NR | 現在のレコード番号 | 行の識別・条件分岐 |
| NF | フィールド数 | 列数の把握 |
| FS | 区切り文字 | フィールド分割(-F指定) |
解説
入力データを確認しながら処理を実行することで、awkの動作理解が容易になる。
NR・NF・FSの組み合わせで行列ベースの柔軟な抽出が可能。
ENDブロックを用いた処理結果の集計とレポート出力
ファイル作成
cat << 'EOF' > input.txt
apple 100
banana 200
apple 150
banana 50
orange 300
EOF
実行コマンド
awk '{ sum[$1]+=$2 } END { for (k in sum) print k, sum[k] }' input.txt
実行結果
apple 250
banana 250
orange 300
仕組み
| 要素 | 内容 |
|---|---|
| $1 | 1列目(キー:商品名) |
| $2 | 2列目(値:数値) |
| sum[$1]+=$2 | 商品ごとに合計値を加算 |
| END | 全行処理後に実行されるブロック |
| for (k in sum) | 連想配列の全キーをループ |
| print k, sum[k] | 集計結果を出力 |
解説
awkのENDブロックを使うことで、全データ処理後にまとめて集計・レポート出力が可能です。
連想配列を活用することでキーごとの柔軟な集計が実現できます。
制御構造(if, for, while)による複雑なロジックの構築
ファイル作成
cat << 'EOF' > input.txt
apple 10
banana 5
orange 20
grape 15
EOF
ファイル作成
cat << 'EOF' > script.awk
{
if ($2 >= 15) {
print $1 " is high"
} else if ($2 >= 10) {
print $1 " is medium"
} else {
print $1 " is low"
}
}
EOF
実行コマンド
awk -f script.awk input.txt
実行結果
apple is medium
banana is low
orange is high
grape is high
仕組み
| 要素 | 内容 |
|---|---|
| script.awk | awkスクリプト本体 |
| $1, $2 | フィールド(1列目:名前, 2列目:数値) |
| if | 条件分岐(15以上) |
| else if | 中間条件(10以上) |
| else | それ以外の処理 |
| -f | awkにスクリプトファイルを指定 |
解説
awkスクリプトを外部ファイル化することで再利用性と可読性が向上します。複雑な条件分岐も整理して管理できるようになります。
system関数を用いたスクリプトの拡張
ファイル作成
cat << 'EOF' > input.txt
apple 100
banana 200
orange 150
EOF
実行コマンド
awk '{ system("echo Item:" $1 ", Price:" $2) }' input.txt
実行結果
Item:apple, Price:100
Item:banana, Price:200
Item:orange, Price:150
仕組み
| 要素 | 内容 |
|---|---|
| awk | テキストを行単位・列単位で処理するスクリプト言語 |
| $1, $2 | 各行の1列目・2列目を表す |
| system関数 | 外部コマンドを実行する関数 |
| echo | 文字列を標準出力するコマンド |
| 処理の流れ | 行読み込み → フィールド分割 → systemで外部実行 |
解説
awkのsystem関数を使うことで、行ごとにシェルコマンドを動的に実行できます。これにより、テキスト処理と外部コマンドを柔軟に組み合わせた拡張が可能になります。
シェルスクリプト(bash)内にawkスクリプトを埋め込む作法
ファイル作成
cat << 'DATA' > input.txt
Alice 80
Bob 65
Charlie 90
DATA
ファイル作成
cat << 'EOF' > script.sh
#!/bin/bash
# awk script を埋め込んで処理
awk '{
if ($2 >= 70) {
print $1 " : Pass"
} else {
print $1 " : Fail"
}
}' input.txt
EOF
実行コマンド
chmod +x script.sh
./script.sh
実行結果
Alice : Pass
Bob : Fail
Charlie : Pass
仕組み
| 要素 | 内容 | 説明 |
|---|---|---|
| シェルスクリプト | script.sh | 全体の制御を行う |
| ヒアドキュメント | cat << 'DATA' | 入力データを生成 |
| awk script | awk '...' | テキスト処理ロジック |
| フィールド参照 | $1, $2 | スペース区切りの列 |
| 条件分岐 | if ($2 >= 70) | 数値判定 |
| 出力 | 加工結果表示 |
解説
bash内にawkを直接書くことで、外部ファイル不要で簡潔にテキスト処理が可能。
ヒアドキュメントと組み合わせると、再現性の高いスクリプトになる。
大規模データ処理時のパフォーマンス最適化と注意点
ファイル作成
cat << 'EOF' > input.txt
id,name,score
1,Alice,82
2,Bob,91
3,Charlie,78
4,David,88
5,Eve,95
EOF
ファイル作成
cat << 'EOF' > process.awk
BEGIN { FS="," }
NR>1 {
sum += $3
count++
}
END {
print "Average:", sum/count
}
EOF
ファイル作成
cat << 'EOF' > filter.awk
BEGIN { FS="," }
NR==1 || $3 >= 90
EOF
ファイル作成
cat << 'EOF' > skip_header.awk
BEGIN { FS="," }
NR>1 {
print $0
}
EOF
実行コマンド
awk -f process.awk input.txt
実行結果
Average: 86.8
実行コマンド
awk -f filter.awk input.txt
実行結果
id,name,score
2,Bob,91
5,Eve,95
実行コマンド
awk -f skip_header.awk input.txt
実行結果
1,Alice,82
2,Bob,91
3,Charlie,78
4,David,88
5,Eve,95
実行コマンド
awk -f skip_header.awk input.txt | sort -t',' -k3 -nr
実行結果
5,Eve,95
2,Bob,91
4,David,88
1,Alice,82
3,Charlie,78
仕組み
| 項目 | 内容 |
|---|---|
| 入力分割 | FS=","でCSV処理を効率化 |
| スキップ | NR>1でヘッダー除外 |
| 集計 | 逐次加算でメモリ節約 |
| 条件抽出 | 条件一致のみ出力 |
| パイプ連携 | sortで外部処理に委譲 |
| 区切り指定 | -t','で列区切り指定 |
| キー指定 | -k3で3列目基準 |
| 数値ソート | -nで数値比較 |
| 降順ソート | -rで降順 |
解説
awkをスクリプト化すると処理の分割と再利用が容易になります。大規模データではI/O削減とパイプ設計が重要です。
ログファイル解析を自動化する実用スクリプトの作成
ファイル作成
cat << 'EOF' > input.txt
2026-05-01 INFO User login success
2026-05-01 ERROR Database connection failed
2026-05-02 INFO File uploaded
2026-05-02 WARNING Disk space low
2026-05-03 ERROR Timeout occurred
EOF
実行コマンド
awk '$2 == "ERROR" {print $0}' input.txt
実行結果
2026-05-01 ERROR Database connection failed
2026-05-03 ERROR Timeout occurred
実行コマンド
awk '{count[$2]++} END {for (level in count) print level, count[level]}' input.txt
実行結果
INFO 2
ERROR 2
WARNING 1
実行コマンド
awk '$2=="ERROR" {print $1, $3, $4, $5}' input.txt
実行結果
2026-05-01 Database connection failed
2026-05-03 Timeout occurred
仕組み
| 処理内容 | awkの記述 | 説明 |
|---|---|---|
| 条件抽出 | $2 == "ERROR" | 2列目がERRORの行のみ抽出 |
| カウント | count[$2]++ | ログレベルごとに件数集計 |
| 終了処理 | END {} | 全行処理後に結果出力 |
| フィールド参照 | $1, $2 ... | 空白区切りで列を指定 |
解説
awkを使うことでログのフィルタ・集計・整形をワンライナーで実現できる。
シンプルながら強力で、運用現場の自動化に非常に有効。
構文エラーと意図しない動作の回避
ファイル作成
cat << 'EOF' > input.txt
apple 10
banana 20
orange 30
EOF
実行コマンド
awk '{ print $1, $2 * 2 }' input.txt
実行結果
apple 20
banana 40
orange 60
実行コマンド
awk 'NF == 2 { sum += $2 } END { print sum }' input.txt
実行結果
60
実行コマンド
awk '{ if ($2 ~ /^[0-9]+$/) print $1 ":" $2 }' input.txt
実行結果
apple:10
banana:20
orange:30
仕組み
| 要素 | 内容 | エラー回避ポイント |
|---|---|---|
| awk '{ ... }' | 各行に対して処理を実行 | クォートの閉じ忘れに注意 |
| $1, $2 | フィールド(列)参照 | 区切り文字の設定ミスを避ける |
| NF == 2 | フィールド数チェック | 不正な行の処理を防止 |
| ~ /^[0-9]+$/ | 正規表現で数値判定 | 型の不一致による誤動作を回避 |
| END { ... } | 全行処理後の処理 | 初期化忘れや変数未定義を防ぐ |
解説
awkスクリプトでは入力形式の前提を明確にし、条件チェック(NFや正規表現)を入れることで構文エラーや意図しない動作を防げます。
awkのscript活用まとめ
awkは軽量ながら強力なテキスト処理ツールであり、scriptとして体系的に使うことで真価を発揮します。
BEGINとENDの活用、組み込み変数の理解、制御構造の習得が基礎となります。
さらに外部連携やbash統合により実務レベルの自動化が可能です。
エラー回避とパフォーマンス意識を持ち、段階的にスキルを積み上げることが重要です。

![[sed] 実行して理解 指定した範囲の行を削除 文字列のsed](https://running-terminal-commands.com/wp-content/uploads/thumbnail_sed_1920_1080.png.webp)