はじめに
テキスト処理を効率よく行いたいときに役立つのがawkです。
その中でもgsubは文字列の置換を柔軟に行える重要な関数です。
しかし初学者にとっては、構文や挙動が少し分かりにくく、思った通りに動かないことも多いです。
この記事では、awkのgsubをテーマに、基本構造から実践的な使い方までを順序立てて解説します。
特に初心者がつまずきやすいポイントに注目しながら、読み物として理解できるように整理しています。
参考元: GNU awk
gsub関数の基本構造
ファイル作成
cat << 'EOF' > input.txt
apple orange apple grape
EOF
実行コマンド
awk '{ gsub("apple", "banana"); print }' input.txt
実行結果
banana orange banana grape
実行コマンド
awk '{ count = gsub("apple", "banana"); print count, $0 }' input.txt
実行結果
2 banana orange banana grape
仕組み
| 要素 | 内容 |
|---|---|
| gsub(検索, 置換) | 行全体($0)を対象に文字列を置換 |
| 戻り値 | 置換された回数を返す |
| デフォルト対象 | $0(行全体) |
| 影響範囲 | 行内のすべての一致箇所が対象 |
解説
基本的に行全体 $0 に対して gsub が適用されます。
戻り値を使うことで置換回数も同時に確認できます。
一括置換と初回置換の使い分け
ファイル作成
cat << 'EOF' > input.txt
apple apple banana apple
EOF
実行コマンド
awk '{ gsub("apple","orange"); print }' input.txt
実行結果
orange orange banana orange
実行コマンド
awk '{ sub("apple","orange"); print }' input.txt
実行結果
orange apple banana apple
仕組み
| 関数 | 動作 | 置換回数 | 用途 |
|---|---|---|---|
| gsub | 指定文字列をすべて置換 | 複数回 | 全体を一括変換したい場合 |
| sub | 最初に一致した文字列のみ置換 | 1回のみ | 先頭や最初の1箇所だけ変更したい場合 |
解説
gsubは行全体に対して一括で置換を行い、subは最初に一致した1箇所のみを置換します。
用途に応じて使い分けることで、意図しない過剰置換を防げます。
正規表現を用いたパターンマッチングによる置換
ファイル作成
cat << 'EOF' > input.txt
apple 100
banana 200
apple 300
grape 150
EOF
実行コマンド
awk '{ gsub(/apple/, "orange"); print }' input.txt
実行結果
orange 100
banana 200
orange 300
grape 150
実行コマンド
awk '{ gsub(/[0-9]+/, "&円"); print }' input.txt
実行結果
apple 100円
banana 200円
apple 300円
grape 150円
仕組み
| 要素 | 内容 |
|---|---|
| gsub | 文字列全体に対して正規表現で一致した部分をすべて置換 |
| /apple/ | 置換対象のパターン(正規表現) |
| "&" | マッチした文字列そのものを再利用 |
| 置換後の行を出力 |
解説
awkのgsubは正規表現にマッチしたすべての箇所を一括置換できるのが特徴です。
パターンと置換文字列を柔軟に組み合わせることで多様なテキスト加工が可能です。
メタ文字($、*、+など)を置換対象にする際のエスケープ処理
ファイル作成
cat << 'EOF' > input.txt
price=$100
pattern=***
math=a+b+c
EOF
実行コマンド
awk '{ gsub(/\$/, "USD"); print }' input.txt
実行結果
price=USD100
pattern=***
math=a+b+c
実行コマンド
awk '{ gsub(/\*\*\*/, "###"); print }' input.txt
実行結果
price=$100
pattern=###
math=a+b+c
実行コマンド
awk '{ gsub(/\+/, "-"); print }' input.txt
実行結果
price=$100
pattern=***
math=a-b-c
仕組み
| メタ文字 | エスケープ方法 | 理由 |
|---|---|---|
| $ | \$ | 行末アンカーとして解釈されるため |
| * | \* | 直前要素の繰り返しとして扱われるため |
| + | \+ | 1回以上の繰り返しの意味を持つため |
| \ | \\ | エスケープ文字自身を表現するため |
解説
awk の gsub は正規表現を使うため、メタ文字はそのままでは特別な意味になります。
そのため、バックスラッシュでエスケープして「文字として扱う」必要があります。
特定のカラム(列)のみを対象にgsubを適用する方法
ファイル作成
cat << 'EOF' > input.txt
id,name,price
1,apple,100yen
2,banana,200yen
3,orange,300yen
EOF
実行コマンド
awk -F',' '{gsub(/yen/, "", $3); print}' OFS=',' input.txt
実行結果
id,name,price
1,apple,100
2,banana,200
3,orange,300
仕組み
| 要素 | 内容 |
|---|---|
| -F',' | フィールド区切りをカンマに設定 |
| $3 | 3列目(price列)を指定 |
| gsub(/yen/,"",$3) | 3列目内の「yen」を削除 |
| OFS=',' | 出力時もカンマ区切りにする |
| 行全体を出力 |
解説
特定カラムは $n で指定し、その変数に対して gsub を使うことで部分的な置換が可能です。
gsubの戻り値(置換回数)を利用した条件分岐の実装
ファイル作成
cat << 'EOF' > input.txt
apple orange apple banana
grape apple melon
banana orange
EOF
実行コマンド
awk '{
count = gsub(/apple/, "APPLE")
if (count > 0) {
print "[置換あり:" count "] " $0
} else {
print "[置換なし] " $0
}
}' input.txt
実行結果
[置換あり:2] APPLE orange APPLE banana
[置換あり:1] grape APPLE melon
[置換なし] banana orange
仕組み
| 要素 | 内容 |
|---|---|
| gsub(/apple/, "APPLE") | apple を APPLE に全置換 |
| 戻り値 | 置換した回数を返す |
| count > 0 | 1回以上置換された行を判定 |
| 条件分岐 | 置換の有無で出力内容を変更 |
解説
gsubは置換回数を返すため、その値を使って「該当文字が含まれていたか」を判定できます。
これにより、awk単体で柔軟な条件分岐が実装できます。
外部変数やシェル変数から置換後の文字列を動的に渡す手法
ファイル作成
cat << 'EOF' > input.txt
Hello NAME, welcome to PLACE.
EOF
実行コマンド
name="Alice"
place="Tokyo"
awk -v name="$name" -v place="$place" '{
gsub(/NAME/, name);
gsub(/PLACE/, place);
print
}' input.txt
実行結果
Hello Alice, welcome to Tokyo.
仕組み
| 要素 | 内容 | 役割 |
|---|---|---|
| -v name=... | シェル変数をawkに渡す | 外部変数の受け取り |
| gsub(/A/, B) | パターンAをBに全置換 | 文字列の動的置換 |
| /NAME/ | 置換対象の正規表現 | マッチ条件 |
| 処理後の行を出力 | 結果表示 |
解説
awkの-vオプションを使うことでシェル変数を安全に渡し、gsubで動的に文字列を置換できます。
環境変数や引数ベースの柔軟なテキスト加工に適しています。
大量のログファイルを高速に処理するためのgsub最適化のコツ
ファイル作成
cat << 'EOF' > input.txt
ERROR: user_id=123 failed login
INFO: user_id=456 success
ERROR: user_id=789 failed login
EOF
実行コマンド
awk '{ gsub(/ERROR/, "WARN"); print }' input.txt
実行結果
WARN: user_id=123 failed login
INFO: user_id=456 success
WARN: user_id=789 failed login
実行コマンド
awk 'BEGIN{pattern="ERROR"} { gsub(pattern, "WARN"); print }' input.txt
実行結果
WARN: user_id=123 failed login
INFO: user_id=456 success
WARN: user_id=789 failed login
実行コマンド
awk '{ if ($0 ~ /ERROR/) gsub(/ERROR/, "WARN"); print }' input.txt
実行結果
WARN: user_id=123 failed login
INFO: user_id=456 success
WARN: user_id=789 failed login
仕組み
| 最適化ポイント | 内容 | 効果 |
|---|---|---|
| 固定文字列の変数化 | BEGINでパターンを変数に格納 | 正規表現の再評価を削減 |
| 条件付きgsub | if ($0 ~ /ERROR/)で事前判定 | 不要な置換処理を回避 |
| 最小限の処理 | 必要な行だけgsub実行 | 大量ログで高速化 |
解説
gsubは全行に対して実行するとコストが高いため、条件分岐や変数化で無駄な評価を減らすのが重要です。
特に大量ログではこの差が大きく効きます。
gsub適用後の$0(レコード全体)の再構築挙動
ファイル作成
cat << 'EOF' > input.txt
foo bar baz
EOF
実行コマンド
awk '{ gsub(/foo/, "XXX"); print $0 }' input.txt
実行結果
XXX bar baz
実行コマンド
awk '{ gsub(/foo/, "XXX", $1); print $0 }' input.txt
実行結果
XXX bar baz
実行コマンド
awk '{ gsub(/foo/, "XXX", $1); print $1, $2, $3 }' input.txt
実行結果
XXX bar baz
仕組み
| 操作内容 | 対象 | $0(レコード全体)の変化 | 備考 |
|---|---|---|---|
| gsub(/foo/, "XXX") | $0 | 自動で再構築される | 全体に直接適用 |
| gsub(/foo/, "XXX", $1) | $1 | $0も再構築される | フィールド変更がトリガー |
| $1を書き換え後 print | $1 | 再構築済みの$0が出力 | OFSで結合される |
| $0を書き換えず print | - | 元の$0が出力 | フィールド変更なし |
解説
awkではフィールド($1など)を書き換えると、$0は自動的に再構築されます。
この挙動を知らないと「部分変更のはずが全体が変わる」落とし穴になります。
awkとgsubで実現する効率的なテキスト処理のポイント
awkのgsubは単なる文字列置換にとどまらず、正規表現や条件分岐、外部変数との連携など多くの機能と組み合わせて使える強力なツールです。
基本構造を理解し、一括置換と初回置換の違いを把握することで、意図した通りの処理ができるようになります。
また、エスケープやカラム指定、戻り値の活用といったポイントを押さえることで、より実践的なスクリプトが書けます。
大量データを扱う場面では最適化も意識しながら、awkとgsubを使いこなして効率的なテキスト処理を実現していきましょう。

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