awk コマンドとは
awk は、テキストファイルや標準入力を行・フィールド単位で処理するプログラミング言語かつコマンドです。列の抽出・集計・条件フィルタリング・フォーマット変換など、CSVやログファイルの加工に特に強力です。sed が行単位の置換・削除に適しているのに対し、awk はフィールド(列)単位の処理や数値計算を得意とします。
構文(Syntax)
awk [オプション] 'pattern { action }' [ファイル...]
主なオプション一覧
| オプション | 説明 | 使用例 |
|---|---|---|
-F SEP | フィールド区切り文字を指定(デフォルトはスペース) | awk -F: '{print $1}' /etc/passwd |
-v VAR=VAL | 外部変数を渡す | awk -v OFS=, '{print $1, $2}' file |
-f FILE | awk スクリプトをファイルから読み込む | awk -f script.awk data.txt |
主な組み込み変数
| 変数 | 説明 |
|---|---|
$0 | 行全体 |
$1, $2, … | 各フィールド(1番目、2番目、…) |
NF | 現在行のフィールド数 |
NR | 現在までの処理行数(行番号) |
FS | 入力フィールド区切り文字(-F と同等) |
OFS | 出力フィールド区切り文字(デフォルト: スペース) |
ORS | 出力レコード区切り文字(デフォルト: 改行) |
FILENAME | 現在処理中のファイル名 |
実行例
特定の列(フィールド)を抽出する
# 1列目のみ表示
awk '{print $1}' file.txt
# 3列目と 5列目を空白区切りで表示
awk '{print $3, $5}' file.txt
区切り文字を指定して CSV を処理する
# CSVの 1列目(名前)のみ抽出
awk -F, '{print $1}' data.csv
# :区切りの /etc/passwd からユーザ名とホームディレクトリを表示
awk -F: '{print $1, $6}' /etc/passwd
出力例:
root /root
daemon /usr/sbin
...
条件に合った行だけ表示する
# 3列目が 100 以上の行だけ表示
awk '$3 > 100 {print $0}' file.txt
# 1列目が "ERROR" の行だけ表示(grep 的な使い方)
awk '$1 == "ERROR" {print $0}' app.log
# "WARN" を含む行だけ表示(正規表現マッチ)
awk '/WARN/ {print $0}' app.log
数値集計(合計・平均)
# 2列目の合計を求める
awk '{sum += $2} END {print "Total:", sum}' sales.txt
# 平均値を求める
awk '{sum += $2; count++} END {print "Average:", sum/count}' scores.txt
出力例:
Total: 45230
行番号を付けて表示する
awk '{print NR, $0}' file.txt
出力例:
1 Alice 25 engineer
2 Bob 30 manager
3 Carol 28 designer
出力フォーマットを指定する
# printf で列幅を整えて表示
awk '{printf "%-10s %5d\n", $1, $2}' data.txt
# 出力フィールド区切り文字を変える(スペースをタブに)
awk 'BEGIN{OFS="\t"} {print $1, $2, $3}' data.txt
複数ファイルを指定して処理する
# 複数の CSV ファイルをまとめて処理
awk -F, '{print $1, $3}' file1.csv file2.csv file3.csv
# find と組み合わせて複数ファイルを対象に
find . -name "*.log" | xargs awk '/ERROR/ {print FILENAME, $0}'
BEGIN / END ブロックでヘッダー・フッターを追加
awk 'BEGIN {print "Name Score"} {print $1, $2} END {print "---"}' scores.txt
出力例:
Name Score
Alice 95
Bob 80
---
最後の列(列数が不定の場合)を表示する
# $NF で最後のフィールドを取得
awk '{print $NF}' file.txt
# 最後から 2番目のフィールド
awk '{print $(NF-1)}' file.txt
パイプ処理で grep ・ sed と組み合わせる
# grep で絞り込んでから awk で列を抽出
grep "^2024" access.log | awk '{print $7}'
# ps の出力をフィルタリングしてプロセス ID だけ表示
ps aux | awk '$3 > 5.0 {print $1, $2, $3}'
# df の出力から使用率 80%以上のディスクを表示
df -h | awk 'NR>1 && $5+0 > 80 {print $0}'
→ grep コマンドの使い方、find コマンドの使い方、xargs コマンドの使い方、sed コマンドの使い方 も併せて確認してください。
関連コマンド
grep: パターンにマッチする行を抽出する。awkの前段に置いて対象行を絞り込むのに使いやすい- find : 対象ファイルを検索し、
xargs awkで複数ファイルを一括処理するときに連携する xargs:findやgrepの出力をawkの引数として渡すことで複数ファイルの一括処理ができるsed: 行単位の置換・削除に特化。フィールド処理ならawk, 置換ならsedと使い分ける- ログ調査の実務パターン : grep・awk・sed を組み合わせてログから原因を特定する手順をまとめている
備考
awkには主に GNU awk(gawk)・ mawk ・ nawk の3種がある。Linux のデフォルトは多くの場合 gawk、macOS は BSD awk。微妙な差異があるため、POSIX 準拠で書くと安全。NR(行番号)を活用して「1行目はヘッダーなのでスキップ」(NR > 1)などの実務パターンが多い。- 複雑な処理は
-fオプションでスクリプトファイル(.awk)に分離すると管理しやすい。
FAQとよくあるつまずき
awk は慣れるまで挙動が分かりにくい部分があります。ここではよくある疑問とつまずきをまとめます。
Q1. awk と grep・sed はどう使い分ける?
grep は行の抽出、sed は行単位の置換・削除に向いています。awk は列(フィールド)単位の抽出・集計・数値計算が必要な場合に選びます。実務では grep で行を絞り込み、awk で列を加工するパイプ処理がよく使われます。
Q2. シェル変数を awk スクリプト内で使うには?
-v オプションで渡すのが確実です。コマンドライン末尾に var=value を置く方法もありますが、その変数は BEGIN ブロックの実行後(ファイル処理が始まってから)にしか反映されないため、BEGIN 内で参照すると空になります。
# OK: BEGINブロックでも値が入る
name="report"
awk -v n="$name" 'BEGIN{print n}'
# NG: BEGINブロックでは空になる
awk 'BEGIN{print n}' n="$name" file.txt
Q3. 数値で比較しているのに意図しない行が混ざる
awk はフィールドが数値に見えるかどうかで比較方法(数値比較/文字列比較)を自動判定します。数値に見えない文字列は文字コード順で比較されるため、$1 > 5 のような条件に文字列の行が紛れ込むことがあります。$1+0 > 5 のように明示的に数値化すると確実です。
# 文字列が紛れ込むことがある
awk '$1 > 5 {print $1}' data.txt
# +0 で数値として比較する
awk '$1+0 > 5 {print $1}' data.txt
Q4. CSV の1行目(ヘッダー)を処理対象から外したい
NR(行番号)を条件に使い、NR > 1 で先頭行をスキップします。
awk -F, 'NR > 1 {print $1}' data.csv
参考
- manページ: man7.org gawk(1)
- GNU awk マニュアル: https://www.gnu.org/software/gawk/manual/gawk.html

コメント