sed(Stream EDitor)は、テキストを1行ずつ処理して、文字列の置換や行の抽出・削除を行うLinuxの定番コマンドです。もっともよく使うのが文字列の置換で、ファイルの中の特定の文字を一括で書き換えたり、設定ファイルの値を変更したりできます。grepが「検索」、sedは「置換・編集」と覚えると分かりやすいです。
つまずきやすいのは、置換が「各行で最初に見つかった1つ」だけになること(すべて置換するにはgが必要)と、-iを付けるとファイルが直接書き換わる(取り消せない)ことです。この記事では、実機のLinux(WSLのDebian)で実際にコマンドを動かしながら、sedの使い方を整理します。
- 置換は
sed "s/古い/新しい/" ファイル。ただし各行で最初の1つだけ置換されます。 - 行内のすべてを置換するには末尾に
g(s/古い/新しい/g)を付けます。 - 大文字小文字を無視するには
i(s/../../gi)を付けます。 - パスなど
/を含む置換は、区切り文字を|などに変えると書きやすいです。 -iを付けるとファイルを直接書き換えます(取り消し不可・要注意)。- 行の抽出は
-n "2,3p"、行の削除は"2d"です。
検索のgrepコマンド、ファイル検索のfindコマンド、ほかの基本はよく使うLinuxコマンドまとめもあわせて参考になります。
sedの基本:置換 s///
もっとも基本的な使い方はsed "s/古い文字列/新しい文字列/"です。sは置換(substitute)を表し、スラッシュで区切って「何を」「何に」置き換えるかを指定します。
# ファイルの中の apple を orange に置換して表示 sed "s/apple/orange/" fruits.txt # パイプで受け取った文字列を置換 echo "hello world" | sed "s/world/Linux/" # hello Linux # 元のファイルは変更されず、結果が画面に表示されるだけ # (ファイルを書き換えるには -i が必要・後述)
実機でも、echo "hello world" | sed "s/world/Linux/"はhello Linuxを返しました。sed "s/古い/新しい/"で置換ができます。重要なのは、この時点では元のファイルは変更されず、置換した結果が画面に表示されるだけという点です。まずはこの形で結果を確認し、問題なければ後述の-iでファイルに反映する、という流れが安全です。
行内で全部置換するには /g
ここが最初の注意点です。sed "s/../../"は、各行で最初に見つかった1つだけを置換します。行内のすべての一致を置換するには、末尾にg(global)を付けます。
# g なし: 各行で最初の1つだけ置換 echo "apple apple apple" | sed "s/apple/X/" # → X apple apple(最初だけ) # g あり: 行内すべてを置換 echo "apple apple apple" | sed "s/apple/X/g" # → X X X(全部)
実機で確認したところ、echo "apple apple" | sed "s/apple/X/"はX apple(最初の1つだけ置換)になり、gを付けたs/apple/X/gはX X(すべて置換)になりました。sedの置換は、デフォルトでは各行の最初の一致だけを対象にします。「置換したのに一部しか変わっていない」というときは、gの付け忘れが原因のことがほとんどです。行内のすべてを置き換えたいなら、末尾にgを必ず付けてください。逆に「各行で最初の1つだけ」を狙って置換したいときは、あえてgを付けません。1行に1回しか出てこない文字列なら、どちらでも結果は同じです。
大文字小文字を無視・区切り文字の変更
大文字小文字を区別せずに置換するにはiを付けます(gと併せてgi)。また、パスのように/を含む文字列を置換するときは、区切り文字を/以外(|など)に変えると、エスケープが不要で読みやすくなります。
# i: 大文字小文字を無視(apple も APPLE も置換) echo "apple APPLE" | sed "s/apple/X/gi" # X X # 区切り文字は / 以外でもよい(パスの置換に便利) echo "/usr/local/bin" | sed "s|/usr|/opt|" # /opt/local/bin # / を区切りに使うと \/ とエスケープが必要でわずらわしい # echo "/usr/local" | sed "s/\/usr/\/opt/"
実機でも、s/apple/X/giはappleとAPPLEの両方をXに置換し、s|/usr|/opt|は/usr/local/binを/opt/local/binに置換しました。区切り文字は最初のsの直後の文字で決まるため、s|...|...|のように|を使えば、パスの中の/をエスケープせずに書けます。ファイルパスやURLを置換するときは、この区切り文字の変更が非常に便利です。
-iで直接編集(注意)
ここまでは結果を画面に表示するだけでしたが、-iを付けると、ファイルそのものを直接書き換えます。便利ですが、取り消せないため注意が必要です。
# -i: ファイルを直接書き換える(表示ではなく保存される) sed -i "s/古い/新しい/g" config.txt # 安全な手順: # STEP1 まず -i なしで結果を確認 sed "s/古い/新しい/g" config.txt # STEP2 問題なければ -i を付けて本実行 sed -i "s/古い/新しい/g" config.txt # バックアップを残す(-i.bak で config.txt.bak が作られる) sed -i.bak "s/古い/新しい/g" config.txt
実機で確認したところ、-iを付けずに実行したときは元のファイルは変更されず、-iを付けたときだけファイルの中身が実際に書き換わりました(line→LINEに置換され、保存されました)。-i(in-place)は直接ファイルを上書きするため、取り消せません。置換条件を間違えると、ファイルが壊れてしまう恐れがあります。必ず先に-iを付けずに実行して、置換結果を画面で確認してから、-iを付けて本実行してください。さらに安全にするには、sed -i.bak "..."のように-iのあとに拡張子を付けると、元のファイルがファイル名.bakとしてバックアップされます。大切なファイルを編集するときは、この方法でバックアップを残すのがおすすめです。
行の抽出・削除(p / d)
sedは置換だけでなく、特定の行を抽出したり削除したりもできます。-n "2,3p"で2〜3行目を表示、"2d"で2行目を削除します。
# -n と p: 2〜3行目だけを表示(-n は自動表示を止める) sed -n "2,3p" file.txt # d: 2行目を削除して表示 sed "2d" file.txt # パターンに一致する行だけ表示(grep のような使い方) sed -n "/ERROR/p" app.log # パターンに一致する行を削除 sed "/DEBUG/d" app.log
実機でも、sed -n "2,3p" file.txtは2〜3行目(line2・line3)だけを表示し、sed "2d"は2行目を除いた行を表示しました。-nは「自動で全行を表示する」動作を止めるオプションで、p(print)と組み合わせて「指定した行だけ表示」します。sed -n "/ERROR/p"のようにパターンを指定すると、grepのように一致行だけを表示でき、"/DEBUG/d"で特定パターンの行を削除できます。行番号でも正規表現でも指定できるのがsedの柔軟なところです。
拡張正規表現 -E
sedのパターンは標準では基本正規表現(BRE)ですが、-Eを付けると拡張正規表現(ERE)になり、+や?・|などをそのまま使えます。
# -E: 拡張正規表現(+ ? | () をそのまま使える) echo "foo123bar" | sed -E "s/[0-9]+/#/" # foo#bar # 連続する数字をまとめて置換 echo "a1b22c333" | sed -E "s/[0-9]+/N/g" # aNbNcN # 複数のパターンを | で(error または warning を大文字に) sed -E "s/error|warning/[!]/g" app.log
実機でも、sed -E "s/[0-9]+/#/"はfoo123barの連続する数字123をまとめて#に置換し、foo#barになりました。-Eを付けないと+はそのままの文字として扱われるため、[0-9]+のような「1個以上」を表すパターンでは-Eが必要です。複雑な置換をするときは、-Eを付けて拡張正規表現を使うと書きやすくなります。
主なオプション・書き方一覧
sedでよく使うものをまとめます。
| 書き方 | 働き |
|---|---|
s/古い/新しい/ |
各行で最初の1つを置換 |
s/古い/新しい/g |
行内のすべてを置換 |
s/../../gi |
大文字小文字を無視して置換 |
s|古い|新しい| |
区切り文字の変更(パス向き) |
-i |
ファイルを直接編集(要注意) |
-n "2,3p" |
指定した行を抽出 |
"2d" / "/語/d" |
行番号 / パターンで行を削除 |
-E |
拡張正規表現を有効にする |
よくある失敗
gを付けず一部しか置換されない
各行で最初の1つだけ置換されます。すべて置換するには末尾にgを付けます。
-iで確認せずファイルを壊す
取り消せません。先に-iなしで結果を確認し、-i.bakでバックアップを残します。
パスの / をエスケープしてわかりにくくなる
区切り文字を|などに変えると、エスケープ不要で読みやすくなります。
+ や ? がそのまま扱われる
拡張正規表現には-Eが必要です。付けないと記号がそのままの意味になります。
置換文字列にスラッシュを含めて混乱する
置換内容に/が入るときも、区切り文字を変えると簡単です。
よくある質問
sed "s/古い文字列/新しい文字列/" ファイルを使います。ただし各行で最初に見つかった1つだけが置換されます。行内のすべてを置換したいときは、末尾にgを付けてs/古い/新しい/gとします。この時点では元のファイルは変更されず、結果が画面に表示されるだけです。sedの置換は、デフォルトでは各行で最初の1つだけを対象にします。行内のすべてを置換するには、末尾にg(global)を付けてください。s/apple/X/gのようにすると、その行のappleがすべてXに置き換わります。-iオプションを付けます。sed -i "s/古い/新しい/g" ファイルで、ファイルの中身が直接書き換わります。ただし取り消せないため、先に-iなしで結果を確認してください。-i.bakとすると、元のファイルがファイル名.bakとしてバックアップされます。/以外に変えると簡単です。sed "s|/usr|/opt|"のように|を使えば、パスの中の/をエスケープせずに書けます。区切り文字はsの直後の文字で決まるため、内容に応じて|や#などを使い分けられます。sed -n "2,3p"(2〜3行目を表示)、削除はsed "2d"(2行目を削除)です。パターンでも指定でき、sed -n "/ERROR/p"で一致行を表示、sed "/DEBUG/d"で一致行を削除できます。まとめ
- 置換は
sed "s/古い/新しい/"。各行で最初の1つだけ置換されます。 - 行内すべてを置換するには末尾に
gを付けます。 - 大小無視は
i、パスの置換は区切り文字を|などに変えると便利です。 -iはファイルを直接編集(取り消し不可)。先に-iなしで確認します。- 行の抽出は
-n "2,3p"、削除は"2d"や"/語/d"です。
sedは、テキストの置換・編集をコマンド1つで行える強力なツールです。「全置換にはg」「-iは確認してから」の2点さえ押さえれば、設定ファイルの一括変更やログの整形を効率よくこなせます。まずは-iなしの置換で結果を確かめながら、少しずつ使いこなしていきましょう。

