awk ワンライナー集 - 実務で使う 30 パターン

awk ワンライナー集 - 実務で使う 30 パターン

この記事でできること

  • awkフィールド抽出・集計・置換の実務パターンを即戦力として使える
  • CSV/TSV・ログ・数値データなど用途別に 30 パターンを整理
  • コピペして awk を先頭に置くだけで動くワンライナーを習得できる

結論:awk の 3 つの使い道

  1. フィールド抽出awk '{print $N}' で列を切り出す(cut より強力)
  2. 集計・計算 — END ブロックで合計・平均・最大値を出す
  3. 変換・整形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

パターンマッチ・フィルタ — 条件に合う行だけ抽出するには?

awkgrep より条件を細かく指定できる。列を指定した絞り込みが強み。

パターン 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.txt

NR==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]}'   # 値ごと件数

次に読む