タイトル: 複数ファイル内の文字列を一括置換する方法
SEOタイトル: Linuxで複数ファイルの文字列を一括置換|find・sed・xargsの安全手順
| この記事の要点 |
|
やりたいこと
あるフォルダ以下の複数ファイルにまたがる文字列を、一括で置換したいというニーズです。設定ファイル一斉更新、リネーム反映、URL の変更などで頻出します。Linux/macOS では find + sed の組み合わせが定番です。
定番の書き方
find /path/to/dir -type f -print0 | xargs -0 sed -i "s/置換前文字列/置換後文字列/g"
| 部品 | 役割 |
|---|---|
find /path/to/dir -type f | 指定ディレクトリ以下のファイルを列挙 |
-print0 | NUL 区切りで出力(スペース・改行入りのファイル名対策) |
xargs -0 | NUL 区切りで読み取り、sed の引数に展開 |
sed -i "s/A/B/g" | ファイル内の A をすべて B に置換し、ファイルを直接書き換える |
使用例
# /etc/myapp 以下の "Windows" を "Linux" に一括置換
find /etc/myapp -type f -print0 | xargs -0 sed -i "s/Windows/Linux/g"
# 拡張子で絞る
find ./src -type f -name "*.php" -print0 | xargs -0 sed -i "s/old_func/new_func/g"
必ず dry-run(プレビュー)してから実行
# 1. どのファイルに含まれているか確認
grep -rl "置換前文字列" /path/to/dir
# 2. 実際にどう変わるかプレビュー(sed -i ではなく出力に流す)
grep -rl "置換前文字列" /path/to/dir | xargs sed -n 's/置換前文字列/置換後文字列/gp'
# 3. 問題なければ本番実行
grep -rlZ "置換前文字列" /path/to/dir | xargs -0 sed -i "s/置換前文字列/置換後文字列/g"
本番置換の前に必ず対象ファイルと差分の確認を行うのが鉄則。grep -lr でテキストファイルだけに絞ると、画像 / アーカイブなどバイナリへの誤適用を防げます。
バックアップ付きで安全に
# -i.bak を付けると、元ファイルを .bak に残してから書き換える
find /path/to/dir -type f -name "*.conf" -print0 \
| xargs -0 sed -i.bak "s/old.example.com/new.example.com/g"
# 上手くいったら .bak を一括削除
find /path/to/dir -type f -name "*.bak" -delete
macOS の BSD sed は-i の後に拡張子が必須(sed -i '' "s/.../.../g" のように空文字列でも明示)。Linux と macOS 両対応スクリプトでは -i.bak 形式が無難です。
区切り文字を変える(パスを含む置換)
置換対象に /(スラッシュ)が多く含まれるときは、sed の区切り文字を | や # に変えると読みやすくなります。
# パスの置換でスラッシュをエスケープしなくて済む
find . -type f -name "*.conf" -print0 \
| xargs -0 sed -i "s|/var/log/old|/var/log/new|g"
正規表現とエスケープ
# 拡張正規表現を使う
find . -type f -name "*.txt" -print0 \
| xargs -0 sed -i -E "s/[0-9]{4}-[0-9]{2}-[0-9]{2}/YYYY-MM-DD/g"
# キャプチャを使った置換
find . -type f -name "*.html" -print0 \
| xargs -0 sed -i -E 's|href="/old/([^"]+)"|href="/new/\1"|g'
特定ディレクトリを除外
# node_modules / .git は除外
find . \
\( -name node_modules -o -name .git -o -name vendor \) -prune \
-o -type f -print0 \
| xargs -0 sed -i "s/古い社名/新しい社名/g"
perl で複数行・複雑な置換
複雑な正規表現や非貪欲マッチが必要なときは perl -i -pe が便利です。
find . -type f -name "*.md" -print0 \
| xargs -0 perl -i -pe 's/\bfoo\b/bar/g'
# 複数行マッチ
find . -type f -name "*.html" -print0 \
| xargs -0 perl -i -0pe 's|||gs'
VS Code / IDE での代替
「Ctrl + Shift + H」でプロジェクト全体の検索と置換ができます。差分プレビュー付き・選択置換も可能で、誤適用のリスクが低く便利です。スクリプト化が必要なケース以外は GUI が早いことも多い。
本番運用のチェックリスト
- パスは絶対パスで書く
- 必ず
grep -rlで対象ファイル数を確認 - 差分は
sed -n 'p'やdiffで事前プレビュー - 本番直前にディレクトリごと
tarでバックアップ - 失敗時の復旧コマンドを準備(バックアップから戻す)
- Git 管理下なら事前コミット&ブランチ作成で差分検証
関連
- Linux — 親カテゴリ
- find / xargs / grep / sed / awk — テキスト処理コマンド
- perl -i -pe — 複雑な置換
- diff / patch — 差分の確認と適用
- VS Code / IDE の検索置換 — GUI での代替