awk ワンライナー集 - 実務で使う 30 パターン
この記事でできること
awkでフィールド抽出・集計・置換の実務パターンを即戦力として使える- CSV/TSV・ログ・数値データなど用途別に 30 パターンを整理
- コピペして
awkを先頭に置くだけで動くワンライナーを習得できる
結論:awk の 3 つの使い道
- フィールド抽出 —
awk '{print $N}'で列を切り出す(cutより強力) - 集計・計算 — END ブロックで合計・平均・最大値を出す
- 変換・整形 —
sub/gsubで正規表現置換、printfでフォーマット整形
前提
- GNU awk(
gawk)を想定。macOS 標準のawkは POSIX 準拠で機能が一部異なる - サンプルは stdin をパイプで受け取るワンライナーとしても動く
awk の基本構文はどう書くのか?
awk 'パターン { アクション }' ファイル の形式で動く。パターンが空なら全行に、アクションが空なら {print} が適用される。
# 基本形
awk '{ アクション }' ファイル
awk 'パターン' ファイル
awk 'パターン { アクション }' ファイルよく使う組み込み変数:
| 変数 | 意味 |
|---|---|
$0 |
行全体 |
$1, $2... |
1列目、2列目... |
NF |
フィールド数(列数) |
NR |
現在の行番号(全ファイル通算) |
FNR |
現ファイル内の行番号 |
FS |
入力区切り文字(デフォルト: スペース/タブ) |
OFS |
出力区切り文字(デフォルト: スペース) |
# -F で区切り文字を指定
awk -F: '{print $1}' /etc/passwd # コロン区切りで1列目
awk -F, '{print $2}' data.csv # CSV の 2 列目フィールド操作 — どうやって列を抽出・変換するのか?
特定フィールドの抽出・組み合わせ・並び替えが awk の最頻出用途だ。
パターン 1:特定の列を出力
awk '{print $2}' file.txt # 2列目
awk '{print $1, $3}' file.txt # 1列目と3列目をスペース区切りで
awk '{print $1 "\t" $3}' file.txt # タブ区切りで出力パターン 2:フィールドの並び替え
# 1列目と2列目を入れ替えて出力
awk '{print $2, $1}' file.txtパターン 3:最後の列と末尾から N 番目
awk '{print $NF}' file.txt # 最後の列
awk '{print $(NF-1)}' file.txt # 末尾から2列目パターン 4:区切り文字を変換して出力
# コロン区切りをカンマ区切りに変換
awk -F: '{OFS=","; $1=$1; print}' file.txt
# スペース区切りをタブ区切りに変換
awk '{OFS="\t"; $1=$1; print}' file.txt$1=$1 の代入は awk に OFS を使って行全体を再構築させる慣用句。値は変わらないが内部的に $0 が OFS で再生成される。
パターン 5:フィールド数が N 列の行だけ出力
awk 'NF==5' file.txt # ちょうど 5 列の行 awk 'NF>=3' file.txt # 3 列以上の行
パターン 6:空白を詰めて複数の区切りに対応
# 複数スペース・タブが混在する行を整形
awk '{$1=$1; print}' file.txtパターンマッチ・フィルタ — 条件に合う行だけ抽出するには?
awk は grep より条件を細かく指定できる。列を指定した絞り込みが強み。
パターン 7:文字列を含む行を抽出
awk '/ERROR/' logfile # ERROR を含む行(grep と同等) awk '/^2026/' access.log # 2026 で始まる行 awk '/ERROR|WARN/' logfile # ERROR または WARN を含む行
パターン 8:特定の列で絞り込み
awk '$3 == "200"' access.log # 3列目が 200 の行 awk '$2 > 100' data.txt # 2列目が 100 より大きい行 awk '$1 ~ /^user/' data.txt # 1列目が user で始まる行 awk '$1 !~ /^#/' config.txt # 1列目が # で始まらない行(コメント除外)
パターン 9:AND / OR 条件
awk '$1 == "GET" && $9 >= 500' access.log # AND awk '$3 == "404" || $3 == "500"' access.log # OR
パターン 10:空行をスキップ
awk 'NF > 0' file.txt # フィールドがある行だけ(空行除外) awk '!/^$/' file.txt # 空行を除外(正規表現版)
行番号・範囲 — 特定の行を取り出すには?
パターン 11:特定行番号を出力
awk 'NR==3' file.txt # 3行目だけ awk 'NR>=5 && NR<=10' file.txt # 5〜10行目
パターン 12:ヘッダ行をスキップ
awk 'NR>1' data.csv # 1行目(ヘッダ)をスキップ
パターン 13:奇数行・偶数行を抽出
awk 'NR%2==1' file.txt # 奇数行 awk 'NR%2==0' file.txt # 偶数行
パターン 14:連番を付けて出力
awk '{print NR ": " $0}' file.txt # 行番号 + コロンで番号付け
awk '{printf "%04d %s\n", NR, $0}' file.txt # ゼロパディングパターン 15:パターン間の範囲を出力
# START から END が現れる行まで出力(両端を含む) awk '/START/,/END/' file.txt # ヘッダの次の行から最初の空行まで出力 awk '/^---$/,/^$/' file.txt
集計・計算 — 数値データをどう集計するのか?
BEGIN / END ブロックを使うと全行を処理した後に集計結果を出力できる。
パターン 16:列の合計
awk '{sum += $1} END {print sum}' data.txt
awk -F, '{sum += $3} END {print sum}' data.csv # CSV の 3 列目パターン 17:平均
awk '{sum += $1; count++} END {print sum/count}' data.txtパターン 18:最大値・最小値
awk 'NR==1 {max=$1; min=$1} {if($1>max) max=$1; if($1<min) min=$1} END {print "max:"max, "min:"min}' data.txtパターン 19:行数カウント
awk 'END {print NR}' file.txt # wc -l 相当
awk '/ERROR/ {count++} END {print count}' logfile # 条件付きカウントパターン 20:値ごとの件数集計(ヒストグラム)
# 3列目の値ごとに件数を集計
awk '{count[$3]++} END {for(k in count) print k, count[k]}' access.log
# HTTP ステータスコードの集計(件数の降順で表示)
awk '{count[$3]++} END {for(k in count) print count[k], k}' access.log | sort -rnパターン 21:重複しない値の一覧
# 1列目のユニーク値(出現順を保持) awk '!seen[$1]++' file.txt # 全行が重複していない行のみ(行全体でユニーク化) awk '!seen[$0]++' file.txt
!seen[$1]++ は「seen[$1] が 0(未登録)なら出力し、インクリメントで次回は出力しない」という慣用句。ソートが不要なため sort -u より柔軟で、出現順を保持できる。
文字列操作 — テキストをどう変換・整形するのか?
パターン 22:文字列置換(sub / gsub)
# 最初のマッチだけ置換(sub)
awk '{sub(/foo/, "bar"); print}' file.txt
# 全マッチを置換(gsub)
awk '{gsub(/foo/, "bar"); print}' file.txt
# 特定列だけ置換
awk '{gsub(/http:/, "https:", $1); print}' file.txtパターン 23:大文字・小文字変換
awk '{print toupper($0)}' file.txt # 全て大文字
awk '{print tolower($1)}' file.txt # 1列目だけ小文字パターン 24:部分文字列を取り出す
# substr(文字列, 開始位置, 長さ) — 1 始まり
awk '{print substr($1, 1, 8)}' file.txt # 1列目の先頭 8 文字
awk '{print substr($1, 5)}' file.txt # 1列目の 5 文字目以降パターン 25:フィールド長でフィルタ
awk 'length($1) > 10' file.txt # 1列目が 10 文字より長い行 awk 'length > 80' file.txt # 行全体が 80 文字より長い行
printf で整形出力 — どうやって揃えた表を作るのか?
print では列幅が揃わないケースに printf を使うと表形式にできる。
パターン 26:列を揃えて出力
# 左揃え 20 文字幅 + 右揃え 8 文字幅
awk '{printf "%-20s %8s\n", $1, $2}' file.txt
# 数値を小数点以下 2 桁で出力
awk '{printf "%.2f\n", $1}' data.txtパターン 27:CSV から表形式に変換
awk -F, '{printf "%-15s %-10s %-8s\n", $1, $2, $3}' data.csv複数ファイル・ファイル間の比較
パターン 28:ファイルごとにヘッダをスキップしてファイル名付き出力
# FNR は現ファイル内の行番号、NR は全体の行番号
awk 'FNR>1 {print FILENAME, $0}' *.csvパターン 29:2 ファイルを比較して差分を出力
# file1 にあって file2 にない行(簡易 diff)
awk 'NR==FNR {a[$0]=1; next} !a[$0]' file1.txt file2.txtNR==FNR は「最初のファイルを処理中」を意味する定番イディオム。next で次の行へスキップし、2ファイル目では a の存在チェックを行う。
パターン 30:BEGIN ブロックで区切り文字を事前設定
# BEGIN で変数を初期化、END で集計結果を出力
awk 'BEGIN {FS=","; OFS="\t"} {print $1, $2, $3}' data.csv
awk 'BEGIN {print "name\tscore"} {print $1, $2} END {print "---"}' data.txtチートシート — よく使うパターン早見表
フィールド操作
awk '{print $1}' # 1列目
awk '{print $NF}' # 最後の列
awk '{print $(NF-1)}' # 末尾から2列目
awk -F, '{print $2}' # CSV の 2 列目
awk -F: '{OFS=","; $1=$1; print}' # コロン→カンマ変換フィルタ
awk 'NR>1' # ヘッダ行をスキップ awk '/ERROR/' # ERROR を含む行 awk '$3 >= 500' # 3列目が 500 以上 awk '!seen[$0]++' # 重複行を除外 awk 'NF>0' # 空行を除外
集計
awk '{sum+=$1} END{print sum}' # 合計
awk 'END{print NR}' # 行数(wc -l 相当)
awk '{c[$1]++} END{for(k in c) print k, c[k]}' # 値ごと件数