はじめに
テキスト処理を効率化したいと考えたとき、awkは非常に強力なツールです。
その中でもsub関数は、文字列の一部を置換するための基本的かつ重要な機能です。
しかし初学者にとっては、どのように使うのか、gsubとの違いは何か、正規表現の扱い方などでつまずきやすいポイントが多くあります。
本記事では、sub関数の役割と構文から始まり、実務で役立つ使い方までを丁寧に解説します。
参考:GNU awk
sub関数の役割と構文
ファイル作成
cat << 'EOF' > input.txt
apple orange apple
banana apple grape
EOF
実行コマンド
awk '{ sub("apple","APPLE"); print }' input.txt
実行結果
APPLE orange apple
banana APPLE grape
仕組み
| 項目 | 内容 |
|---|---|
| 関数名 | sub |
| 役割 | 最初に一致した文字列のみ置換 |
| 構文 | sub(正規表現, 置換文字列, 対象) |
| デフォルト対象 | $0(行全体) |
| 戻り値 | 置換した場合1、しない場合0 |
解説
subは各行で最初に一致した部分だけを置換する関数です。
すべて置換したい場合はgsubを使用します。
sub関数とgsub関数の違い
ファイル作成
cat << 'EOF' > input.txt
apple apple apple
banana apple banana
EOF
実行コマンド
awk '{ sub(/apple/, "orange"); print }' input.txt
実行結果
orange apple apple
banana orange banana
実行コマンド
awk '{ gsub(/apple/, "orange"); print }' input.txt
実行結果
orange orange orange
banana orange banana
仕組み
| 関数 | 置換回数 | 対象 | 戻り値 | 特徴 |
|---|---|---|---|---|
| sub | 1回のみ | 最初にマッチした部分 | 置換した回数(0 or 1) | 最初だけ置換 |
| gsub | すべて | マッチした全て | 置換した回数(整数) | 全体を一括置換 |
解説
subは最初の一致だけを置換し、gsubは一致したすべてを置換します。
用途に応じて使い分けます。
sub関数での正規表現
ファイル作成
cat << 'EOF' > input.txt
apple 100
banana 200
apple 300
EOF
実行コマンド
awk '{ sub(/apple/, "orange"); print }' input.txt
実行結果
orange 100
banana 200
orange 300
実行コマンド
awk '{ sub(/[0-9]+/, "NUM"); print }' input.txt
実行結果
apple NUM
banana NUM
apple NUM
仕組み
| 要素 | 内容 |
|---|---|
| sub関数 | 最初にマッチした部分のみ置換する |
| 第1引数 | 正規表現(例: /apple/, /[0-9]+/) |
| 第2引数 | 置換後の文字列 |
| 対象 | 各行($0)に対して処理される |
| 戻り値 | 置換が成功すると1、失敗すると0 |
解説
awkのsubは「最初の1箇所だけ置換」するのが特徴です。
複数置換したい場合はgsubを使います。
特定の列(フィールド)だけを置換対象にする指定方法
ファイル作成
cat << 'EOF' > input.txt
id name age city
1 Alice 25 Tokyo
2 Bob 30 Osaka
3 Carol 22 Nagoya
EOF
実行コマンド
awk '{ sub(/2[0-9]/, "XX", $3); print }' input.txt
実行結果
id name age city
1 Alice XX Tokyo
2 Bob 30 Osaka
3 Carol XX Nagoya
実行コマンド
awk '{ sub(/A.*/, "NAME", $2); print }' input.txt
実行結果
id name age city
1 NAME 25 Tokyo
2 Bob 30 Osaka
3 Carol 22 Nagoya
仕組み
| 要素 | 内容 |
|---|---|
| $1, $2, ... | フィールド(列)を指定 |
| sub(正規表現, 置換文字, 対象) | 指定フィールド内のみ置換 |
| $3 | 3列目(age)だけ対象 |
| $2 | 2列目(name)だけ対象 |
| 全体行を出力(変更反映) |
解説
awk の sub は第3引数にフィールドを指定することで、特定列だけを安全に置換できます。
これにより他の列へ影響を与えず、ピンポイントな編集が可能です。
変数への代入と元のデータへの影響
ファイル作成
cat << 'EOF' > input.txt
apple 100
banana 200
apple 300
EOF
実行コマンド
awk '{ tmp=$1; sub("apple","orange",tmp); print $1, tmp }' input.txt
実行結果
apple orange
banana banana
apple orange
実行コマンド
awk '{ sub("apple","orange",$1); print $1 }' input.txt
実行結果
orange
banana
orange
仕組み
| 処理内容 | 対象 | 元データへの影響 | 説明 |
|---|---|---|---|
| tmp=$1; sub(..., tmp) | 変数tmp | なし | コピーに対して置換するため元は変わらない |
| sub(..., $1) | フィールド$1 | あり | フィールド自体を書き換える |
解説
subは指定した変数やフィールドを直接書き換える関数です。
コピーした変数に対して使うかどうかで、元データへの影響が変わります。
sub関数で「空文字」へ置換することによる文字列の削除
ファイル作成
cat << 'EOF' > input.txt
apple 123
banana 456
cherry 789
EOF
実行コマンド
awk '{ sub(/[0-9]+/, ""); print }' input.txt
実行結果
apple
banana
cherry
仕組み
| 要素 | 内容 |
|---|---|
| sub | 最初に一致したパターンを置換 |
| /[0-9]+/ | 1文字以上の数字にマッチ |
| "" | 空文字(削除を意味する) |
| $0 | 行全体(省略時は自動適用) |
| 置換後の行を出力 |
解説
sub関数でマッチした部分を空文字に置き換えることで、特定の文字列を削除できます。
この例では数字部分のみを削除し、文字列だけを残しています。
マッチした文字列を再利用する方法
ファイル作成
cat << 'EOF' > input.txt
apple 100
banana 200
apple 300
EOF
実行コマンド
awk '{ if (sub(/apple/, "&_fruit")) print }' input.txt
実行結果
apple_fruit 100
apple_fruit 300
仕組み
| 要素 | 内容 |
|---|---|
| sub | 最初にマッチした文字列を置換する |
| /apple/ | 置換対象の正規表現 |
| "&_fruit" | & はマッチした文字列そのもの(ここでは apple) |
| if (sub(...)) | 置換が成功した行のみ処理(戻り値が1) |
| 条件に一致した行を出力 |
解説
マッチ部分は & を使うことで再利用できます。
これにより、元の文字列を保持しつつ柔軟に加工できます。
ログファイル整形やCSV加工で役立つsub関数の例
ファイル作成
cat << 'EOF' > input.txt
2026-04-30 ERROR UserID=1234 Message=LoginFailed
2026-04-30 INFO UserID=5678 Message=LoginSuccess
2026-04-30 ERROR UserID=9999 Message=Timeout
EOF
実行コマンド
awk '{ sub(/ERROR/, "WARN"); print }' input.txt
実行結果
2026-04-30 WARN UserID=1234 Message=LoginFailed
2026-04-30 INFO UserID=5678 Message=LoginSuccess
2026-04-30 WARN UserID=9999 Message=Timeout
実行コマンド
awk '{ sub(/UserID=[0-9]+/, "UserID=****"); print }' input.txt
実行結果
2026-04-30 ERROR UserID=**** Message=LoginFailed
2026-04-30 INFO UserID=**** Message=LoginSuccess
2026-04-30 ERROR UserID=**** Message=Timeout
実行コマンド
awk '{ sub(/Message=/, "Msg="); print }' input.txt
実行結果
2026-04-30 ERROR UserID=1234 Msg=LoginFailed
2026-04-30 INFO UserID=5678 Msg=LoginSuccess
2026-04-30 ERROR UserID=9999 Msg=Timeout
仕組み
| 要素 | 内容 |
|---|---|
| sub関数 | 指定した正規表現に最初に一致した部分のみ置換 |
| 書式 | sub(正規表現, 置換文字列, 対象) |
| 対象省略 | $0(行全体)が対象になる |
| gsubとの違い | subは1回だけ、gsubは全て置換 |
| 戻り値 | 置換が成功すると1、失敗すると0 |
解説
awk の sub はログ整形やCSV加工で「一部だけ変えたい」ときに便利です。
全置換したい場合は gsub と使い分けるのがポイントです。
大量データ処理時に意識すべき置換の効率
ファイル作成
cat << 'EOF' > input.txt
apple banana apple grape apple
banana apple orange apple
EOF
実行コマンド
awk '{ sub("apple", "APPLE"); print }' input.txt
実行結果
APPLE banana apple grape apple
banana APPLE orange apple
実行コマンド
awk '{ gsub("apple", "APPLE"); print }' input.txt
実行結果
APPLE banana APPLE grape APPLE
banana APPLE orange APPLE
仕組み
| 項目 | sub | gsub |
|---|---|---|
| 置換回数 | 各行で最初の1回のみ | 各行のすべて |
| パフォーマンス | 高速(置換回数が少ない) | やや低速(全置換するため) |
| 用途 | 最初の一致のみ変更したい場合 | 全一致を変更したい場合 |
| 動作単位 | 行ごと | 行ごと |
解説
大量データでは不要な全置換を避け、subで最小限の処理にすると効率が向上します。
用途に応じてsubとgsubを使い分けるのが重要です。
エスケープ処理で躓かないためのポイント
ファイル作成
cat << 'EOF' > input.txt
path=/home/user/docs
EOF
実行コマンド
awk '{ sub(/\//, "_"); print }' input.txt
実行結果
path=_home/user/docs
実行コマンド
awk '{ sub(/\//, "\\/"); print }' input.txt
実行結果
path=\/home/user/docs
仕組み
| 要素 | 内容 | ポイント |
|---|---|---|
| /\// | / を表す正規表現 | / は区切り文字なのでエスケープが必要 |
| sub() | 最初に一致した文字列を置換 | 1回のみ置換 |
| "\\/" | \/ を出力 | バックスラッシュは2重にエスケープ |
| "_" | 単純な置換文字 | エスケープ不要 |
解説
awkのsubでは「正規表現」と「文字列」の両方でエスケープが必要になるため、バックスラッシュが増える点に注意するのが重要です。
awkのsub関数を使いこなすためのまとめ
sub関数はシンプルながら奥が深い機能です。
最初の一致のみを置換するという特性を理解し、gsubとの違いを意識することで、より正確なテキスト処理が可能になります。
また、正規表現やフィールド指定、エスケープ処理といったポイントを押さえることで、実務レベルのデータ加工にも対応できるようになります。
awkを使った効率的な処理を実現するために、まずはsub関数からしっかり理解していくことが大切です。

![[sed] 実行して理解 指定した範囲の行を削除 文字列のsed](https://running-terminal-commands.com/wp-content/uploads/thumbnail_sed_1920_1080.png)