awk コマンド|テキストの抽出・集計・変換を実務パターンで解説

コマンドリファレンス

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 FILEawk スクリプトをファイルから読み込む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 : findgrep の出力を 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

参考

Bash玄

はじめまして!Bash玄です。

エンジニアとしてシステム運用に携わる中で、手作業の多さに限界を感じ、Bashスクリプトを活用して業務を効率化したのがきっかけで、この道に入りました。「手作業は負け」「スクリプトはシンプルに」をモットーに、誰でも実践できるBashスクリプトの書き方を発信しています。

このサイトでは、Bashの基礎から実践的なスクリプト作成まで、初心者でもわかりやすく解説しています。少しでも「Bashって便利だな」と思ってもらえたら嬉しいです!

# 好きなこと
- シンプルなコードを書くこと
- コマンドラインを快適にカスタマイズすること
- 自動化で時間を生み出すこと

# このサイトを読んでほしい人
- Bashに興味があるけど、何から始めればいいかわからない人
- 定型業務を自動化したい人
- 効率よくターミナルを使いこなしたい人

Bashの世界に一歩踏み出して、一緒に「Bash道」を極めていきましょう!

Bash玄をフォローする

コメント