- 技術 💻
awkコマンドの使い方|実例50と集計・ログ解析、gawkとmawkの違い
awkコマンドとは、テキストを1行ずつ読み、空白やカンマで区切った「列」を取り出したり、条件で絞り込んだり、合計や件数を集計したりできるコマンドです。ログから特定の列だけを抜き出す、CSV の部署ごとの平均を出す、アクセスログのステータスコードを数える、といった作業を1行で書けます。
この記事では、すべての例を「入力ファイル → コマンド → 出力」の3点セットで、実際に実行した結果をそのまま載せています。上位の解説で省かれがちな連想配列でのグループ集計、printf での整形、gsub・split などの文字列関数、2つのファイルの結合、CSV(--csv)、ログ解析まで扱い、さらに gawk・mawk・BSD 系 awk など5つの実装で同じコードを動かして違いを比較しました。
検証環境:Ubuntu 24.04。GNU awk(gawk)5.3.2 を主に使い、比較用に gawk 5.2.1、mawk 1.3.4、original-awk 20231127(BWK awk、macOS や BSD の awk の系統)、BusyBox 1.36.1 の awk を使用しました。gawk の最新版は 5.4.0(2026年2月リリース)です。
awkコマンドの早見表(逆引き)
| やりたいこと | コマンド |
|---|---|
| 2列目を表示 | awk '{ print $2 }' file |
| 1列目と3列目を表示 | awk '{ print $1, $3 }' file |
| 最後の列 / 最後から2番目 | awk '{ print $NF }' / awk '{ print $(NF-1) }' |
| カンマ区切り / コロン区切り | awk -F, '...' / awk -F: '...' |
| 3列目が4以上の行 | awk '$3 >= 4' file |
| 「pen」を含む行 | awk '/pen/' file |
| 2列目が「e」で始まる行 | awk '$2 ~ /^e/' file |
| 1行目(見出し)を飛ばす | awk 'NR > 1' file |
| 2〜3行目 | awk 'NR >= 2 && NR <= 3' file |
| 行番号をつける | awk '{ print NR ": " $0 }' file |
| 区切り文字を変えて出力 | awk -F, -v OFS='\t' '{ $1 = $1; print }' file |
| 列の合計 | awk '{ s += $3 } END { print s }' file |
| 列の平均 | awk '{ s += $3 } END { print s / NR }' file |
| グループごとの合計 | awk '{ a[$2] += $3 } END { for (k in a) print k, a[k] }' file |
| 重複行を除く(順番を保つ) | awk '!seen[$0]++' file |
| 桁をそろえて表示 | awk '{ printf "%-8s %5d\n", $1, $2 }' file |
| 文字列の置換 | awk '{ gsub(/old/, "new"); print }' file |
| 空行を除く | awk 'NF' file |
| 行数を数える | awk 'END { print NR }' file |
| 2つのファイルを結合 | awk 'NR == FNR { a[$1] = $2; next } { print $0, a[$1] }' f1 f2 |
| シェルの値を渡す | awk -v min=80 '$2 >= min' file |
| 引用符付き CSV | gawk --csv '{ print $3 }' file.csv(gawk 5.3 以降) |
| ステータスコードを集計 | awk '{ c[$9]++ } END { for (k in c) print k, c[k] }' access.log |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「awkコマンドの使い方|実例50と集計・ログ解析、gawkとmawkの違い」
awkの基本の書き方
awk のプログラムは「パターン { アクション }」の形です。パターンに合う行に対して、{ } の中の処理を実行します。パターンを省略するとすべての行が対象、アクションを省略すると行をそのまま表示します。
awk 'パターン { アクション }' ファイル
flowchart LR
A[BEGIN ブロック<br>最初に1回] --> B[1行読む<br>$1 $2 ... に分割]
B --> C{パターンに合う?}
C -- はい --> D[アクション実行]
C -- いいえ --> E{次の行がある?}
D --> E
E -- はい --> B
E -- いいえ --> F[END ブロック<br>最後に1回]
プログラムは必ずシングルクォート '...' で囲みます。ダブルクォートで囲むとシェルが $2 を先に展開してしまいます(後述のつまずき参照)。
| 変数 | 意味 |
|---|---|
$0 |
行全体 |
$1 $2 … |
1列目、2列目 … |
NF |
その行の列数($NF は最後の列) |
NR |
通算の行番号 |
FNR |
ファイルごとの行番号 |
FS / OFS |
入力 / 出力の区切り文字(既定は空白) |
RS / ORS |
入力 / 出力の行の区切り(既定は改行) |
FILENAME |
今読んでいるファイル名 |
この記事で使う入力ファイル
# orders.txt(日付 品名 数量 単価)
2026-09-01 pen 3 120
2026-09-01 note 5 200
2026-09-02 pen 2 120
2026-09-02 eraser 4 80
2026-09-03 note 1 200
2026-09-03 pen 6 120
# members.csv
id,name,dept,score
1,Sato,dev,82
2,Suzuki,sales,75
3,Tanaka,dev,91
4,Ito,hr,68
5,Kato,sales,88
# prices.txt # sales.txt # dup.txt
pen 120 pen 3 apple
note 200 note 5 banana
eraser 80 eraser 4 apple
marker 2 cherry
banana
列を取り出す($1・-F)
$2 で2列目を取り出せます。既定の区切りは「連続した空白やタブ」で、-F で区切り文字を変えられます。print でカンマを入れると、出力では空白(OFS)で区切られます。
$ awk '{ print $2 }' orders.txt
pen
note
pen
eraser
note
pen
$ awk '{ print $4, $3, $2 }' orders.txt # 列の順番を入れ替える
120 3 pen
200 5 note
120 2 pen
80 4 eraser
200 1 note
120 6 pen
$ awk -F, '{ print $2 }' members.csv
name
Sato
Suzuki
Tanaka
Ito
Kato
/etc/passwd のようなコロン区切りも同じです(例はサンプルの users.txt)。
$ awk -F: '{ print $1, $7 }' users.txt
root /bin/bash
daemon /usr/sbin/nologin
alice /bin/bash
bob /bin/zsh
$ awk -F '[=:]' '/=/ { print $2 }' config.txt # 区切りに正規表現も使える
localhost
8080
db.local
5432
条件で行を絞り込む
パターンには比較(== >= など)、正規表現(/.../)、~(一致)・!~(不一致)、&& || を使えます。
$ awk '$3 >= 4' orders.txt
2026-09-01 note 5 200
2026-09-02 eraser 4 80
2026-09-03 pen 6 120
$ awk '/pen/' orders.txt
2026-09-01 pen 3 120
2026-09-02 pen 2 120
2026-09-03 pen 6 120
$ awk '$2 ~ /^e/ { print $2, $3 }' orders.txt
eraser 4
$ awk '$2 !~ /pen/ { print $2 }' orders.txt
note
eraser
note
$ awk -F, 'NR > 1 && $3 == "dev" { print $2 }' members.csv
Sato
Tanaka
$ awk -F, 'NR > 1 { print $2, ($4 >= 80 ? "合格" : "再挑戦") }' members.csv
Sato 合格
Suzuki 再挑戦
Tanaka 合格
Ito 再挑戦
Kato 合格
/pen/ は行のどこかに「pen」があれば一致します。列を限定したいときは $2 ~ /pen/、完全一致なら $2 == "pen" と書きます。
NR・NF・FS・OFS を使う
$ awk 'NR == 2' orders.txt
2026-09-01 note 5 200
$ awk 'NR >= 2 && NR <= 3' orders.txt
2026-09-01 note 5 200
2026-09-02 pen 2 120
$ awk '{ print NR ": " $0 }' prices.txt
1: pen 120
2: note 200
3: eraser 80
$ awk '{ print NF, $NF, $(NF-1) }' orders.txt | head -2
4 120 3
4 200 5
$ awk 'BEGIN { FS = ","; OFS = "\t" } { $1 = $1; print }' members.csv | head -3
id name dept score
1 Sato dev 82
2 Suzuki sales 75
$ awk -F, -v OFS=, '{ print $2, $1 }' members.csv | head -3
name,id
Sato,1
Suzuki,2
OFS を変えただけでは print(行全体の $0)の区切りは変わりません。$1 = $1 のように列に代入すると行が組み立て直され、OFS が反映されます。実際に BEGIN{OFS="-"} で print; $1=$1; print を実行すると、pen 120 → pen-120 となりました。
合計・平均・最大を求める
変数は宣言なしで使え、最初は 0(空文字)です。END ブロックは全行を読んだ後に1回だけ実行されるので、集計結果の表示に使います。
$ awk '{ sum += $3 } END { print "合計:", sum }' orders.txt
合計: 21
$ awk -F, 'NR > 1 { sum += $4; n++ } END { printf "平均: %.1f (%d人)\n", sum / n, n }' members.csv
平均: 80.8 (5人)
$ awk -F, 'NR > 1 { if (max == "" || $4 > max) { max = $4; who = $2 } } END { print "最高:", who, max }' members.csv
最高: Tanaka 91
$ awk 'END { print NR }' orders.txt
6
最大値は max = 0 から始めると、すべて負の値のときに正しく求まりません。max == ""(まだ値がない)を条件に入れて、最初の値で初期化するのが確実です。
連想配列でグループ集計する
連想配列は「文字列をキーにできる配列」です。qty[$2] += $3 と書くと、品名ごとに数量を足し込めます。SQL の GROUP BY に近い集計が1行で書けます。
$ awk '{ qty[$2] += $3 } END { for (k in qty) print k, qty[k] }' orders.txt
eraser 4
pen 11
note 6
$ awk '{ qty[$2] += $3 } END { for (k in qty) print k, qty[k] }' orders.txt | sort -k2,2nr
pen 11
note 6
eraser 4
$ awk '{ amount[$2] += $3 * $4 } END { for (k in amount) printf "%-8s %6d\n", k, amount[k] }' orders.txt | sort
eraser 320
note 1200
pen 1320
$ awk -F, 'NR > 1 { cnt[$3]++; total[$3] += $4 } END { for (d in cnt) printf "%s %d人 平均%.1f\n", d, cnt[d], total[d] / cnt[d] }' members.csv | sort
dev 2人 平均86.5
hr 1人 平均68.0
sales 2人 平均81.5
for (k in 配列) の順番は決まっていません。同じデータでも、gawk・mawk は eraser pen note、original-awk は pen note eraser、BusyBox は note pen eraser の順でした。並び順が必要なら | sort に渡します(gawk だけは PROCINFO["sorted_in"] = "@ind_str_asc" でキー順にできます)。
重複を除く・出現回数を数える
$ awk '!seen[$0]++' dup.txt
apple
banana
cherry
$ awk '{ c[$0]++ } END { for (k in c) print c[k], k }' dup.txt | sort -rn
2 banana
2 apple
1 cherry
!seen[$0]++ は「初めて見た行なら表示」という意味です。seen[$0] は最初 0(偽)なので ! で真になり表示され、その後 ++ で 1 になるため、2回目以降は表示されません。sort | uniq と違い、元の順番を保てます。
printf で整形する
printf "書式", 値... で桁数や小数点をそろえられます。print と違い、改行は \n を自分で書きます。
$ awk -F, 'NR > 1 { printf "%-3s %-8s %5.1f\n", $1, $2, $4 }' members.csv
1 Sato 82.0
2 Suzuki 75.0
3 Tanaka 91.0
4 Ito 68.0
5 Kato 88.0
$ awk 'BEGIN { printf "%5.2f|%-6s|%06d|%x|%e\n", 3.14159, "ab", 42, 255, 12345.678 }'
3.14|ab |000042|ff|1.234568e+04
| 書式 | 意味 | 例 → 結果 |
|---|---|---|
%s / %-8s |
文字列 / 8桁で左寄せ | "ab" → ab |
%d / %06d |
整数 / 6桁でゼロ埋め | 42 → 000042 |
%5.2f |
全体5桁・小数2桁 | 3.14159 → 3.14 |
%x / %e |
16進数 / 指数表記 | 255 → ff |
%% |
% そのもの |
日本語(全角文字)は1文字でも画面上は2文字分の幅になるため、%-8s で幅をそろえても表示がずれます。表を作るときは見出しを英字にするか、列の区切りをタブ(\t)にすると読みやすくなります。
文字列関数(gsub・sub・split・substr・length・toupper)
| 関数 | 動き |
|---|---|
gsub(正規表現, 置換, 対象) |
すべて置換し、置換した数を返す(対象を省略すると $0) |
sub(正規表現, 置換, 対象) |
最初の1つだけ置換 |
split(文字列, 配列, 区切り) |
分割して配列に入れ、要素数を返す |
substr(文字列, 開始, 長さ) |
部分文字列(開始は1から) |
length(文字列) |
文字数 |
index(文字列, 探す文字列) |
最初に見つかった位置(なければ 0) |
toupper / tolower |
大文字 / 小文字に |
$ awk '{ gsub(/-/, "/", $1); print $1, $2 }' orders.txt | head -2
2026/09/01 pen
2026/09/01 note
$ awk '{ sub(/pen/, "PEN"); print }' prices.txt
PEN 120
note 200
eraser 80
$ awk '{ n = gsub(/a/, "A"); print n, $0 }' dup.txt
1 Apple
3 bAnAnA
1 Apple
0 cherry
3 bAnAnA
$ awk '{ n = split($1, d, "-"); print d[1] "年" d[2] "月" d[3] "日", n }' orders.txt | head -1
2026年09月01日 3
$ awk '{ print substr($1, 1, 3), length($1), toupper($1) }' prices.txt
pen 3 PEN
not 4 NOTE
era 6 ERASER
$ awk '{ print index($0, "an") }' dup.txt
0
2
0
0
2
awk では文字列をつなぐ演算子はなく、並べて書くだけで連結されます(d[1] "年" d[2])。
BEGIN と END
$ awk 'BEGIN { print "品名\t金額" } { print $1 "\t" $2 } END { print "件数:", NR }' prices.txt
品名 金額
pen 120
note 200
eraser 80
件数: 3
BEGIN は1行目を読む前、END は全行を読んだ後に1回だけ実行されます。見出しの表示、FS や OFS の設定は BEGIN、集計結果は END に書きます。
複数のファイルを扱う(FNR・結合)
NR は通算の行番号、FNR はファイルごとの行番号です。NR == FNR は「1つ目のファイルを読んでいる間」だけ真になるため、2つのファイルの結合(JOIN)に使えます。
$ awk 'NR == FNR { price[$1] = $2; next } { print $1, $2, price[$1] * $2 }' prices.txt sales.txt
pen 3 360
note 5 1000
eraser 4 320
marker 2 0
$ awk 'NR == FNR { price[$1] = $2; next } !($1 in price) { print "価格なし:", $1 }' prices.txt sales.txt
価格なし: marker
$ awk 'FNR == 1 { print "==", FILENAME, "==" } { print FNR, $0 }' prices.txt dup.txt
== prices.txt ==
1 pen 120
2 note 200
3 eraser 80
== dup.txt ==
1 apple
2 banana
3 apple
4 cherry
5 banana
1つ目のファイル(prices.txt)で「品名 → 単価」の配列を作り、next で次の行へ進みます。2つ目のファイル(sales.txt)ではその配列を引いて金額を計算します。価格がない marker は price["marker"] が空(0)になるため、($1 in price) で存在を確かめると漏れに気づけます。
-v でシェルの変数を渡す
$ awk -v min=80 -F, 'NR > 1 && $4 >= min { print $2, $4 }' members.csv
Sato 82
Tanaka 91
Kato 88
$ awk -v tax=1.1 '{ printf "%s %d\n", $1, $2 * tax }' prices.txt
pen 132
note 220
eraser 88
シェルの変数を使うときは awk -v min="$MIN" '...' のように -v で渡します。プログラムの中に '"$MIN"' と埋め込むより読みやすく、値に空白や記号があっても安全です。
範囲を指定する・設定ファイルを読む
# config.txt
# settings
[server]
host=localhost
port=8080
[db]
host=db.local
port=5432
$ awk '/^\[db\]/,/^port/' config.txt
[db]
host=db.local
port=5432
$ awk -F= '/^\[/ { sec = $0; next } /=/ { print sec, $1, $2 }' config.txt
[server] host localhost
[server] port 8080
[db] host db.local
[db] port 5432
$ awk 'NF' config.txt | wc -l # 空行を除いた行数
7
/開始/,/終了/ は、開始パターンに合った行から終了パターンに合う行までを対象にします。NF は空行で 0(偽)になるため、awk 'NF' で空行を除けます。
CSV を扱う(-F, の限界と gawk --csv)
-F, は単純にカンマで分けるため、"black, 0.5mm" のように引用符の中にカンマがある CSV は列がずれます。gawk 5.3 以降は --csv オプションで CSV のルール(引用符、"" のエスケープ)どおりに分割できます。
# items_quoted.csv
id,name,memo
1,pen,"black, 0.5mm"
2,note,"A5 ""dot"" grid"
3,eraser,plain
$ awk -F, '{ print NF ": " $3 }' items_quoted.csv
3: memo
4: "black
3: "A5 ""dot"" grid"
3: plain
$ gawk --csv '{ print NF ": " $3 }' items_quoted.csv
3: memo
3: black, 0.5mm
3: A5 "dot" grid
3: plain
| 実装 | --csv の結果 |
|---|---|
| gawk 5.3.2 | 対応(上の結果) |
| original-awk 20231127(BWK awk) | 対応(gawk と同じ結果) |
| gawk 5.2.1(Ubuntu 24.04 の apt) | 非対応(使い方の表示で終了) |
| mawk 1.3.4 | 非対応(mawk: not an option: --csv) |
| BusyBox 1.36.1 | 非対応(awk: unrecognized option '--csv') |
Ubuntu 24.04 の apt で入る gawk は 5.2.1 のため、--csv は使えませんでした。gawk --version でバージョンを確かめ、使えない環境では Python の csv モジュールなどを使うと確実です。
ログを集計する
アクセスログ(共通ログ形式)では、空白区切りで $1 が IP アドレス、$4 が日時、$7 がパス、$9 がステータスコード、$10 がバイト数になります。
# access.log
192.0.2.10 - - [28/Sep/2026:09:12:01 +0900] "GET /index.html HTTP/1.1" 200 5120
192.0.2.11 - - [28/Sep/2026:09:40:22 +0900] "GET /items HTTP/1.1" 200 2048
198.51.100.5 - - [28/Sep/2026:10:05:13 +0900] "POST /login HTTP/1.1" 302 0
192.0.2.10 - - [28/Sep/2026:10:15:47 +0900] "GET /missing HTTP/1.1" 404 512
203.0.113.7 - - [28/Sep/2026:10:59:59 +0900] "GET /items HTTP/1.1" 500 128
192.0.2.10 - - [28/Sep/2026:11:02:30 +0900] "GET /items HTTP/1.1" 200 2048
$ awk '{ st[$9]++ } END { for (s in st) print s, st[s] }' access.log | sort # ステータスコード別の件数
200 3
302 1
404 1
500 1
$ awk '$9 >= 400 { print $4, $7, $9 }' access.log # エラーだけ抜き出す
[28/Sep/2026:10:15:47 /missing 404
[28/Sep/2026:10:59:59 /items 500
$ awk '{ split($4, t, ":"); h[t[2]]++ } END { for (k in h) print k "時", h[k] "件" }' access.log | sort # 時間帯別
09時 2件
10時 3件
11時 1件
$ awk '{ bytes[$1] += $10 } END { for (ip in bytes) print ip, bytes[ip] }' access.log | sort -k2,2nr # IP別の転送量
192.0.2.10 7680
192.0.2.11 2048
203.0.113.7 128
198.51.100.5 0
時間帯別の集計は、$4([28/Sep/2026:10:15:47)を : で split すると2番目の要素が「時」になることを利用しています。
スクリプトファイルにする(-f)
長くなった処理は .awk ファイルに書き、awk -f ファイル名 で実行します。print ... | "sort" のように、awk の中から別のコマンドへ出力を渡すこともできます。
# report.awk 使い方: awk -f report.awk orders.txt
BEGIN {
printf "%-8s %4s %8s\n", "item", "qty", "amount"
}
{
qty[$2] += $3
amount[$2] += $3 * $4
total += $3 * $4
}
END {
for (k in qty)
printf "%-8s %4d %8d\n", k, qty[k], amount[k] | "sort"
close("sort") # sort の出力を先に書き出させる
printf "%-8s %4s %8d\n", "total", "", total
}
$ awk -f report.awk orders.txt
item qty amount
eraser 4 320
note 6 1200
pen 11 1320
total 2840
close("sort") を書かないと、合計行が sort の結果より先に表示されることがあります。ファイルを直接書き換えたいときは、gawk なら gawk -i inplace '{ $2 = $2 * 2 } 1' file(gawk 5.2.1 で動作を確認)が使えます。
gawk・mawk・BSD 系 awk の違い
awk には複数の実装があり、Ubuntu 24.04 の初期状態の awk は mawk でした(gawk を入れると gawk に切り替わります)。macOS や BSD の awk は BWK awk(One True AWK)の系統です。同じコードを5つの実装で動かした結果です。
| 機能 | gawk 5.3.2 | mawk 1.3.4 | original-awk(BWK) | BusyBox |
|---|---|---|---|---|
--csv |
○ | × | ○ | × |
length("日本語")(UTF-8) |
3 | 9(バイト数) | 3 | 9(バイト数) |
toupper("abcab") |
ABCAB |
ABCab |
ABCAB |
ABCab |
gensub()(グループを使う置換) |
○ | × | × | ○ |
asort()(配列の並べ替え) |
○ | × | × | × |
PROCINFO["sorted_in"] |
○ | ×(順不定) | ×(順不定) | ×(順不定) |
IGNORECASE = 1 |
○ | × | × | ○ |
\y(単語の境界) |
○ | × | × | × |
strftime() / systime() |
○ | ○ | ×(未定義エラー) | ○ |
"0x1A" + 0 |
0 | 26 | 0 | 26 |
nextfile、length(配列)、/a{3}/ |
○ | ○ | ○ | ○ |
未対応の関数を呼ぶと、たとえば mawk は mawk: line 2: function gensub never defined、original-awk は original-awk: calling undefined function gensub というエラーになります。
複数の環境で動かすスクリプトは、POSIX の範囲(print、printf、gsub、split、substr、連想配列など)で書くと安心です。日本語の文字数を扱う、CSV を正しく分割する、配列を並べ替えるといった処理が必要なら、gawk を入れて gawk と明示して呼び出します。
sed・cut・Python との使い分け
| ツール | 向いている作業 | 例 |
|---|---|---|
| cut | 区切りが1文字で、列を切り出すだけ | cut -d, -f2 members.csv |
| sed | 行単位の置換・削除・挿入 | sed 's/old/new/g' |
| awk | 列ごとの条件・計算・集計・整形 | awk '{ a[$2] += $3 } END {...}' |
| Python | 引用符付き CSV、JSON、複雑な処理、保守するスクリプト | csv.DictReader |
cut は区切りが連続すると空の列として数えます。printf 'a b\n' | cut -d' ' -f2 は空行を出力しましたが、awk '{ print $2 }' は連続した空白を1つの区切りとして扱い b を出力しました。空白区切りのログやコマンド出力は awk、置換は sed、込み入った CSV や長く保守する処理は Pythonと使い分けると迷いません。
よくあるつまずき
| 症状 | 原因 | 直し方 |
|---|---|---|
| 列ではなく行全体が表示される | awk "{ print $2 }" とダブルクォートで囲み、シェルが $2 を空に展開した |
シングルクォートで囲む |
| 比較が一致しない(Windows で作ったファイル) | 行末に \r(CRLF)が残り、最後の列が ok\r になっている |
{ sub(/\r$/, "") } を先頭に書く |
OFS が反映されない |
列を変更していないので $0 が組み立て直されない |
$1 = $1 を入れる |
| 集計結果の順番がばらばら | for (k in 配列) は順不定 |
| sort に渡す |
1,200 が 1 として計算される |
数値はカンマの手前までしか読まれない | gsub(/,/, "", $3) で除いてから計算 |
| CSV の列がずれる | 引用符の中のカンマで分割された | gawk --csv か Python の csv |
CRLF の例を実際に確かめると、printf 'pen,ok\r\nnote,ng\r\n' で作ったファイルに awk -F, '$2 == "ok"' を実行しても何も表示されず、{ sub(/\r$/, "") } $2 == "ok" にすると pen,ok が表示されました。
よくある質問
Q. awk と gawk は何が違いますか?
A. awk は言語とコマンドの名前で、gawk はその GNU 実装です。環境によって awk の実体が gawk・mawk・BWK awk などに分かれます。awk --version(BWK awk は awk -version)で確かめられます。
Q. 見出し行(1行目)を残したまま集計したいです。
A. NR == 1 { print; next } を先頭に書くと、1行目をそのまま表示して次の行へ進みます。集計から除きたいだけなら、条件に NR > 1 をつけます。
Q. 数値として比較されず、文字列として比較されることはありますか?
A. あります。列の値や -v で渡した値は、数値に見えれば数値として比較されますが、プログラム中に "10" と書いた文字列定数は文字列として比較されます。実際に x = "10"; y = 9; print (x > y) は 0(偽)でした。数値として扱いたいときは x + 0 のように 0 を足します。
Q. 大きなファイルでも使えますか? A. awk は1行ずつ読んで処理するため、ファイル全体をメモリに読み込まずに済みます。ただし連想配列のキーが非常に多いとメモリを使うので、キーの種類が多い集計では注意します。
まとめ
- 基本は
awk 'パターン { アクション }' ファイル。プログラムはシングルクォートで囲む - 列は
$1$NF、区切りは-F、出力の区切りはOFS($1 = $1で反映) - 合計・平均は
ENDで表示、グループ集計は連想配列a[$2] += $3 - 重複除去は
!seen[$0]++、2ファイルの結合はNR == FNR { ...; next } - 整形は
printf、置換・分割はgsubsubsplitsubstr - 引用符付き CSV は gawk 5.3 以降の
--csv。Ubuntu 24.04 の apt 版 gawk 5.2.1 では使えない - 実装で機能が違う(Ubuntu の初期 awk は mawk)。移植性が必要なら POSIX の範囲で書く
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「awkコマンドの使い方|実例50と集計・ログ解析、gawkとmawkの違い」
株式会社RJCでは、ログの確認やデータの集計といった日々の作業を、コマンドを組み合わせて手早く進める工夫をメンバー同士で共有しています。こうした知識を共有しながら、日々技術を磨いています。
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。