こんにちは、かつコーチです。
前回は、grepを使ったテキスト検索の基本と正規表現の入り口を解説しました。
今回は、検索した文字列をそのまま置換できるsedコマンドを解説します。
sedは設定ファイルの一括修正やログ整形など、実務で頻繁に登場するコマンドですが、使い方を誤るとファイルを意図せず書き換えてしまう危険もあります。
この記事を読めば、安全にsedを使いこなすための基本と注意点が身につきます。
sedとは?
ストリームエディタという位置づけ
sed(Stream Editor)は、ファイルの中身を1行ずつ読み込みながら、指定したパターンに従って編集するストリームエディタです。
viやnanoのような対話型のエディタとは異なり、コマンド1行で「どこを」「どう変えるか」を指定し、一括で処理するのが特徴です。
前回解説したgrepが「検索して表示する」コマンドだとすれば、sedは「検索して書き換える」コマンドという位置づけになります。
基本の置換構文
sedで最もよく使う機能が、文字列を置換するsコマンドです。
# "old"を"new"に置換した結果を画面に表示する
sed 's/old/new/' sample.txt
構文はs/検索する文字列/置換後の文字列/という形で、sは「substitute(置換する)」の頭文字です。
このままでは元のファイルは変更されず、置換結果が画面に表示されるだけである点を、まず理解しておくことが重要です。
実際にファイルを置換する
-iオプションでファイルを直接書き換える
置換結果を元のファイルに反映させたい場合は、-i(in-place)オプションを使います。
# config.txt自体を直接書き換える
sed -i 's/old-domain.com/new-domain.com/' config.txt
-iを付けると、確認画面なしにファイルが即座に上書きされます。
この挙動を正しく理解せずに使うと、意図しない書き換えに気づけないまま作業を進めてしまう危険があるため、次の章で紹介する安全策とセットで覚える必要があります。
gオプションで行内のすべてを置換する
sコマンドは、デフォルトでは1行につき最初にマッチした箇所しか置換しません。
# 1行に複数の"foo"があっても、最初の1つしか置換されない
sed 's/foo/bar/' sample.txt
行内のすべての該当箇所を置換したい場合は、末尾にg(global)オプションを付けます。
# 1行内のすべての"foo"を"bar"に置換する
sed 's/foo/bar/g' sample.txt
「一部しか置換されていない」という現象に遭遇したら、まずgを付け忘れていないかを確認するのが定石です。
複数ファイルへの一括適用
sed -iはワイルドカードと組み合わせることで、複数ファイルへの一括置換にも対応できます。
# カレントディレクトリのすべての.confファイルに一括適用する
sed -i 's/old-domain.com/new-domain.com/g' *.conf
前回の記事で紹介したrmのワイルドカード操作と同様に、対象範囲を誤ると被害が広がる操作のため、事前の確認が欠かせません。
置換ミスを防ぐための安全な手順
実行前に必ず対象を確認する
sedで置換する前は、前回学んだgrepで対象行を確認する流れを徹底しましょう。
# 1. まずgrepで置換対象の行を確認する
grep "old-domain.com" config.txt
# 2. -iを付けずに、置換結果を画面上でプレビューする
sed 's/old-domain.com/new-domain.com/g' config.txt
# 3. 問題なければ-iを付けてファイルに反映する
sed -i 's/old-domain.com/new-domain.com/g' config.txt
いきなり-i付きで実行せず、「確認 → プレビュー → 反映」の3段階を踏むことで、意図しない置換を未然に防げます。
バックアップを取りながら置換する
-iにはバックアップ拡張子を指定できるオプションもあり、万が一のために元のファイルを残しておけます。
# .bakという拡張子で元のファイルをバックアップしてから置換する
sed -i.bak 's/old-domain.com/new-domain.com/g' config.txt
このコマンドを実行すると、config.txtが置換された状態で保存されると同時に、config.txt.bakという置換前のバックアップファイルが自動生成されます。
本番環境の設定ファイルを扱うときは、この.bak付きの実行を基本ルールにしておくと安心です。
つまずきやすいポイント:バックアップなしでNginx設定を壊した話
私が本番のNginx設定ファイルをsedで一括置換した際、バックアップを取らずに実行して青ざめた経験があります。
❌ Before:バックアップなしでいきなり-i付きで実行する
# バックアップを取らずに直接ファイルを書き換える
sudo sed -i 's/example.com/example.jp/g' /etc/nginx/sites-available/default
置換自体は成功したのですが、実は正規表現の対象範囲が広すぎて、本来変更したくなかった別の設定項目まで巻き込んで書き換わってしまいました。
nginx -t(設定ファイルの構文チェックコマンド)を実行すると、案の定エラーが出て、Nginxを再起動できない状態に陥りました。
元のファイルの内容を覚えていなかったため、その場で手動修正するしかなく、余計な時間がかかってしまいました。
✅ After:バックアップを取り、変更後は必ず構文チェックする
# バックアップを取りながら置換する
sudo sed -i.bak 's/example.com/example.jp/g' /etc/nginx/sites-available/default
# 設定ファイルの構文が正しいか確認する
sudo nginx -t
# 問題があればバックアップから復元する
sudo cp /etc/nginx/sites-available/default.bak /etc/nginx/sites-available/default
このトラブル以降、本番環境の設定ファイルをsedで書き換えるときは、必ず.bakでバックアップを取り、変更後にサービス固有の構文チェックコマンドを実行する、という手順を徹底するようになりました。
応用・一歩先の使い方
行番号や特定行の指定
sedは、置換対象を行番号で絞り込むこともできます。
# 3行目だけを対象に置換する
sed '3s/old/new/' sample.txt
# 5行目から10行目までを対象に置換する
sed '5,10s/old/new/' sample.txt
ファイル全体ではなく、特定の範囲だけを修正したい場合に便利な指定方法です。
行の削除にも使える
sedは置換だけでなく、条件に合う行を削除するdコマンドも持っています。
# "DEBUG"を含む行を削除した結果を表示する
sed '/DEBUG/d' app.log
grep -vと似た結果になりますが、sedは「削除した結果をファイルに保存する(-iと組み合わせる)」ところまで一気に行える点が異なります。
# DEBUG行を削除してファイルに反映する
sed -i.bak '/DEBUG/d' app.log
まとめ
この記事のポイント
sedはs/検索文字列/置換後文字列/という構文でテキストを置換するストリームエディタ-iオプションを付けるとファイルが直接書き換わるため、扱いには注意が必要- 置換前は
grepで対象を確認し、-iなしでプレビューしてから反映する流れが安全 -i.bakでバックアップを取り、置換後はサービス固有の構文チェックを行う習慣をつける
次に読むべき記事
grepとsedでテキスト処理の基本を押さえたら、次は目的のファイルそのものを探し出すfindコマンドに進みましょう。
→ 次の記事:findコマンドでファイルを検索する
タグ: Linux, 中級者向け, テキスト処理