sedコマンドで文字列を置換する方法|-iの一括置換やファイル編集も

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Linuxtips > sedコマンドで文字列を置換する方法|-iの一括置換やファイル編集も
===== TITLE ===== sedコマンドで文字列を置換する方法|-iの一括置換やファイル編集も ===== DESCRIPTION (entry_text) ===== 「設定ファイルの中の文字列を一括で書き換えたいけど、viで1つずつ修正するのは時間がかかりすぎる」
「sedコマンドの書き方が複雑で、毎回ネットで調べてしまう」
サーバーの構築や設定変更で、設定ファイルの特定の文字列をまとめて置換したい場面は頻繁に発生します。
20年以上サーバーを運用してきた現場では、sedなしの設定変更作業は考えられないほど頻繁に使うコマンドです。

この記事では、テキストを加工する sed(セド)コマンド の実践的な使い方を解説します。
基本的な文字列置換から、ファイルを直接書き換える -i オプション、正規表現を使った高度な置換、findxargs との組み合わせによる複数ファイルの一括置換まで、実務で使える手順を実行例付きでまとめました。

この記事のポイント

・ sed 's/old/new/g' で行内の全マッチを一括置換できる
・ -i オプションでファイルを直接上書き保存できる(-i.bak でバックアップ付き)
・ 正規表現・後方参照を使えば設定値や日付形式の柔軟な置換が可能
・ find / xargs と組み合わせると複数ファイルの一括置換も安全に行える

===== TEXT_MORE (entry_text_more) =====
「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
図解60P/登録10秒/解除も3秒 / 詳細はこちら

sedコマンドとは?(ストリームエディタの基本概念)

sed は「Stream Editor(ストリームエディタ)」の略で、ファイルをviなどのエディタで開かずに、コマンドラインからテキストを加工できるツールです。

動作の流れは次の3ステップです。

・ファイルを1行ずつ読み込む(またはパイプ経由で標準入力を受け取る)
・指定したパターンに一致する部分を変換・削除・追加する
・結果を標準出力に書き出す(-i オプション時はファイルを直接上書き)

最大の特徴は、ファイルを開かずに文字列の置換・削除・追加ができる点です。1つのファイルに対してはもちろん、シェルスクリプトに組み込んで大量のファイルを自動処理することもできます。

viやnanoのような対話型エディタが「ファイルを開いて編集・保存する」のに対し、sedは「コマンド1行でテキスト処理が完結する」ストリーム処理型のツールです。サーバー構築やデプロイ作業の自動化に欠かせない存在です。

基本的な文字列置換(s/検索/置換/)

sed の最も基本的な使い方は、s(substitute:置換)コマンドです。書式は s/検索文字列/置換文字列/ です。

1. 最初にマッチした文字列だけを置換する

デフォルトでは、各行の中で最初にマッチした文字列だけが置換されます。結果は画面に表示され、元のファイルは変更されません。

# old を new に置換して表示する(各行の最初のマッチのみ) $ sed 's/old/new/' sample.txt # 実行例: 同じ文字が複数あっても最初の1か所だけ置換される $ echo "a:b:a:b" | sed 's/a/X/' X:b:a:b

2. 行内のすべてのマッチを置換する(gフラグ)

1行の中に同じ文字列が複数回出現する場合、すべて置換するには末尾に g(global)フラグを付けます。実務ではほとんどの場合 g を付けて使います。

# old をすべて new に置換する $ sed 's/old/new/g' sample.txt # 実行例: すべてのマッチが置換される $ echo "a:b:a:b" | sed 's/a/X/g' X:b:X:b

実際のサーバー作業での使用例(RHEL 9.4 で動作確認済み):

# httpd.conf の Listen ポートを 80 から 8080 に変更して画面確認 [admin@web01 ~]$ echo "Listen 80" | sed 's/80/8080/' Listen 8080 # IP アドレスを複数箇所で置換する [admin@web01 ~]$ echo "server=192.168.1.10 backup=192.168.1.10" | sed 's/192.168.1.10/10.0.0.1/g' server=10.0.0.1 backup=10.0.0.1

3. 大文字・小文字を無視して置換する(Iフラグ)

I フラグを付けると、大文字・小文字を区別せずにマッチさせることができます(GNU sed)。

# Error / error / ERROR いずれもマッチして warning に置換する $ sed 's/error/warning/gI' sample.txt

ファイルを直接書き換える(-i オプション)

ここまでの例はすべて「結果を画面に表示するだけ」で、元のファイルは変更されません。ファイルそのものを書き換えるには -i(in-place)オプションを使います。

1. バックアップを取りながら書き換える(-i.bak)【推奨】

-i の直後に拡張子を指定すると、変更前のファイルがバックアップとして保存されます。本番サーバーの設定ファイルを変更する際は、必ずこの方法を使ってください。

# httpd.conf の ServerName を書き換え、元ファイルを .bak として保存する $ sed -i.bak 's/ServerName old.example.com/ServerName new.example.com/' /etc/httpd/conf/httpd.conf # バックアップファイルが作成されていることを確認する $ ls /etc/httpd/conf/httpd.conf* /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.bak # 実行例: 書き換え前後の確認 $ cat /tmp/test.conf server_name=localhost $ sed -i.bak 's/localhost/192.168.1.10/' /tmp/test.conf $ cat /tmp/test.conf server_name=192.168.1.10

2. バックアップなしで直接書き換える(-i)

バックアップが不要な場合は、拡張子を指定せずに -i だけを付けます。

# バックアップなしで直接書き換える $ sed -i 's/old/new/g' sample.txt

【重要】-i オプションの危険性と対策

-i はファイルを直接上書きするため、間違った置換を実行すると元に戻せません。
本番環境では必ず以下の手順を守ってください。

・まず -i なしで実行して、置換結果を画面で確認する
・問題なければ -i.bak でバックアップ付きで実行する
・バックアップファイルで差分を確認する(diff コマンド)

# 手順1:まず画面で確認する(ファイルは変更されない) $ sed 's/old/new/g' /etc/httpd/conf/httpd.conf # 手順2:問題なければバックアップ付きで実行する $ sed -i.bak 's/old/new/g' /etc/httpd/conf/httpd.conf # 手順3:差分を確認する $ diff /etc/httpd/conf/httpd.conf.bak /etc/httpd/conf/httpd.conf

実務で頻出するsedのパターン

1. 特定の行だけを置換する(行番号指定)

s コマンドの前に行番号を指定すると、その行だけが置換対象になります。

# 5行目だけを置換する $ sed '5s/old/new/' sample.txt # 10行目から20行目までを置換する $ sed '10,20s/old/new/g' sample.txt # "START" を含む行から "END" を含む行の範囲で置換する $ sed '/START/,/END/s/old/new/g' sample.txt

2. 特定の文字列を含む行を削除する(d コマンド)

d(delete)コマンドを使うと、パターンにマッチした行を丸ごと削除できます。設定ファイルから不要な行を取り除く時に便利です。

# "debug" を含む行を削除して表示する $ sed '/debug/d' sample.txt # コメント行(# で始まる行)を削除して表示する $ sed '/^#/d' /etc/httpd/conf/httpd.conf # 空行を削除して表示する $ sed '/^$/d' sample.txt # コメント行と空行を同時に削除する(-e で複数指定) $ sed -e '/^#/d' -e '/^$/d' sample.txt

実行例(コメント行・空行を削除して有効な設定行だけを取り出す):

[admin@web01 ~]$ cat /tmp/sample.conf # This is a comment ServerName www.example.com # Another comment ServerPort 443 [admin@web01 ~]$ sed -e '/^#/d' -e '/^$/d' /tmp/sample.conf ServerName www.example.com ServerPort 443

3. 行の先頭・末尾に文字列を追加する

正規表現の ^(行頭)と $(行末)を活用して、各行の先頭や末尾に文字列を追加できます。

# 各行の先頭に "LOG: " を追加する $ sed 's/^/LOG: /' sample.txt # 各行の末尾に " ;done" を追加する $ sed 's/$/ ;done/' sample.txt

4. コメントアウト・アンコメントを一括で行う

設定ファイルの行頭に # を付ける(コメントアウト)/外す(アンコメント)は、サーバー設定でよく行う作業です。

# "Listen 8080" を含む行をコメントアウトする $ sed -i.bak '/Listen 8080/s/^/#/' /etc/httpd/conf/httpd.conf # 行頭の # を外す(アンコメント) $ sed -i.bak 's/^#Listen 8080/Listen 8080/' /etc/httpd/conf/httpd.conf

5. 特定の行だけを表示する(-n と p の組み合わせ)

-n オプションと p(print)コマンドを組み合わせると、マッチした行だけを表示できます。grep に似た使い方ですが、行番号指定や正規表現の範囲指定で柔軟に絞り込めるのが強みです。

# 5行目だけを表示する $ sed -n '5p' /etc/httpd/conf/httpd.conf # 10行目から20行目までを表示する $ sed -n '10,20p' /etc/httpd/conf/httpd.conf # "Listen" を含む行だけを表示する $ sed -n '/Listen/p' /etc/httpd/conf/httpd.conf

6. 複数の操作を同時に実行する(-e)

-e オプションを使うと、複数の置換や削除を1回のコマンドで実行できます。

# old を new に置換し、さらに空行を削除する $ sed -e 's/old/new/g' -e '/^$/d' sample.txt # 複数の文字列を同時に置換する $ sed -e 's/foo/bar/g' -e 's/baz/qux/g' sample.txt

正規表現を使った高度な置換

sed では基本正規表現(BRE)が使えます。単純な文字列の置換だけでなく、パターンを使った柔軟な置換ができるのがsedの真価です。

まずよく使うパターンを整理しておきます。

パターン 意味 使用例
. 任意の1文字 sed 's/a.c/XYZ/'
* 直前の文字が0回以上 sed 's/ab*/X/'
^ 行頭 sed 's/^#//'
$ 行末 sed 's/ *$//'
[abc] 文字クラス(a・b・cのいずれか) sed 's/[0-9]//g'
\(…\) グループ化(後方参照用) sed 's/\(foo\)bar/\1baz/'

1. 任意の文字列にマッチさせる(.*)

.* は「任意の文字が0回以上」にマッチするパターンです。設定ファイルで「キー名は同じだが値が異なる」行を一括で書き換える時に重宝します。

# "MaxClients" の値が何であっても 256 に書き換える $ sed 's/^MaxClients.*/MaxClients 256/' /etc/httpd/conf/httpd.conf # SELINUX の値を disabled に変更する $ sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config

2. 数字にマッチさせる([0-9])

数字だけを対象にする場合は [0-9] を使います。[0-9]\+ で「1桁以上の数字」にマッチします。

# 数字の連続を "XXX" に置換する $ sed 's/[0-9]\+/XXX/g' sample.txt

※GNU sed の基本正規表現では、+{} などの量指定子はバックスラッシュ付き(\+\{n\})で記述します。拡張正規表現を使いたい場合は -E オプション(または -r)を付けてください。

3. グループ化と後方参照で文字列を並べ替える(\1)

正規表現でマッチした部分を「後方参照」として再利用できます。\(\) で囲んだ部分が \1 ... で参照できます。

# "2024-01-15" のような日付を "2024/01/15" 形式に変換する $ sed 's/\([0-9]\{4\}\)-\([0-9]\{2\}\)-\([0-9]\{2\}\)/\1\/\//g' sample.txt # IPアドレスの第4オクテットだけを変更する(192.168.1.10 → 192.168.1.20) [admin@web01 ~]$ echo "address=192.168.1.10" | sed 's/\(192\.168\.1\.\)10/P/' address=192.168.1.20

この例では、年・月・日をそれぞれ \1 で参照し、区切り文字をハイフンからスラッシュに変換しています。ログファイルの日付形式を統一したい場面などで使えるテクニックです。

4. 拡張正規表現を使う(-E オプション)

-E オプションを付けると、より書きやすい拡張正規表現(ERE)が使えます。
\(…\) の代わりに (…)\+ の代わりに + が使えるなど、記法がシンプルになります。

# 基本正規表現(BRE)での記述 $ sed 's/[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}/DATE/g' log.txt # 拡張正規表現(ERE)で同じことを書く(-E オプション) $ sed -E 's/[0-9]{4}-[0-9]{2}-[0-9]{2}/DATE/g' log.txt # 1文字以上の空白をアンダースコアに変換する $ sed -E 's/ +/_/g' list.txt

5. Windows の改行コード(CR)を削除する

Windows 形式のテキストファイルを Linux で扱う際、行末に不可視の (CR)が混入することがあります。
シェルスクリプトや設定ファイルを Windows 環境で編集した後に Linux で実行するとエラーになる場合、まずこの CR 除去を試してください。

# 行末の CR( )を削除する(Windows改行 → Unix改行 変換) $ sed -i 's/ //' ファイル名 # 行末の余分な空白も合わせて削除する $ sed -i 's/ *$//' ファイル名

行の挿入・追加(i / a コマンド)

置換や削除だけでなく、特定の行の前後にテキストを挿入することもできます。設定ファイルに新しい行を追加する場面で使います。

1. 特定の行の前に挿入する(i コマンド)

i(insert)コマンドで、マッチした行の「前」にテキストを挿入します。

# "Listen 80" の前にコメント行を挿入する $ sed '/Listen 80/i\# Added by admin' httpd.conf

2. 特定の行の後に追加する(a コマンド)

a(append)コマンドで、マッチした行の「後」にテキストを追加します。

# "Listen 80" の後に新しいポート設定を追加する $ sed '/Listen 80/a\Listen 8443' httpd.conf

sedと他のコマンドを組み合わせる(実務Tips)

find + sed で複数ファイルを一括置換する

ディレクトリ内の複数ファイルに対して同じ置換を行いたい場合、find と組み合わせます。

# /var/www/html/ 以下のすべての .html ファイルで old.example.com を new.example.com に置換する $ find /var/www/html/ -name "*.html" -exec sed -i.bak 's/old.example.com/new.example.com/g' {} \; # xargs を使う方法(大量ファイルで高速) $ find /var/www/html/ -name "*.html" | xargs sed -i.bak 's/old.example.com/new.example.com/g' # ファイル名に空白が含まれる場合は -print0 と xargs -0 を組み合わせる $ find /var/www/html/ -name "*.html" -print0 | xargs -0 sed -i.bak 's/old.example.com/new.example.com/g'

-exec は対象ファイルごとに新しいプロセスを起動しますが、xargs はまとめて渡すためプロセス数が削減され、大量ファイルの処理で高速です。

実行例(複数ファイルへの一括置換):

[admin@web01 ~]$ find /etc/httpd/ -name "*.conf" | xargs grep -l "old_server" /etc/httpd/conf/httpd.conf /etc/httpd/conf.d/ssl.conf [admin@web01 ~]$ find /etc/httpd/ -name "*.conf" | xargs sed -i.bak 's/old_server/new_server/g' [admin@web01 ~]$ find /etc/httpd/ -name "*.conf" | xargs grep "new_server" /etc/httpd/conf/httpd.conf:ServerName new_server /etc/httpd/conf.d/ssl.conf:ServerName new_server

パイプで受け取ったテキストをsedで加工する

他のコマンドの出力をパイプで sed に渡し、必要な部分だけを整形することもできます。

# ip addr の出力からIPアドレスの行だけを取り出し、余分な空白を除去する $ ip addr show eth0 | sed -n '/inet /p' | sed 's/^ *//'

awkコマンドとの使い分け

sedとよく比較されるのが awk コマンドです。どちらもテキスト処理ツールですが、得意な用途が異なります。

sed:行単位の置換・削除・挿入が得意。パターン一致の書き換えはsedが高速でシンプルに書ける
awk:列(フィールド)単位の抽出・集計・計算が得意。CSVやログの列処理はawkが向いている

「特定の文字列を書き換えるだけ」ならsed、「列を取り出して集計・比較する」ならawk、が基本の使い分けです。設定ファイルや定型テキストの一括置換であれば、ほぼsedで対応できます。

「sed: -e expression #1」エラーが出た時の対処法

sed を使っていて最もよく遭遇するエラーが「sed: -e expression #1」系です。主な原因と対処法を整理します。

1. デリミタの衝突(パスに / が含まれる場合)

置換対象にファイルパスなどスラッシュ(/)を含む文字列がある場合、デリミタと衝突してエラーになります。
解決策は、デリミタを / 以外の文字(#|)に変えることです。

# NG:パスの / がデリミタと衝突する $ sed 's//var/log/old//var/log/new/' sample.txt # OK:デリミタを # に変更する $ sed 's#/var/log/old#/var/log/new#' sample.txt # OK:デリミタを | に変更する $ sed 's|/var/log/old|/var/log/new|' sample.txt

2. 正規表現の特殊文字のエスケープ忘れ

sed はデフォルトで正規表現を使うため、.(ドット)、*(アスタリスク)、[(角括弧)などの特殊文字は、リテラルとして扱いたい場合にバックスラッシュ(\)でエスケープが必要です。

# NG:ドットが任意の1文字として解釈される $ sed 's/192.168.1.1/10.0.0.1/g' hosts.txt # OK:ドットをエスケープする $ sed 's/192\.168\.1\.1/10.0.0.1/g' hosts.txt

3. 置換が効かない時のチェックポイント

コマンドを実行しても変化がない場合、以下を確認してください。

g フラグ忘れ:行内に複数マッチがある場合、フラグなしでは最初の1か所しか置換されない
特殊文字のエスケープ忘れ. * [ \ などはバックスラッシュでエスケープが必要
シングルクォートとダブルクォートの混同:シェル変数を埋め込む時はダブルクォート、それ以外はシングルクォートを使う

# シェル変数を使う場合はダブルクォートで囲む NEW_SERVER="192.168.1.20" $ sed "s/192\.168\.1\.10//" hosts.txt

4. macOS(BSD sed)との違い

macOS の sed は GNU sed とは挙動が異なります。
特に -i オプションは、macOS では拡張子を必須で指定する必要があります(バックアップ不要な場合でも空文字 '' を渡す必要があります)。

# Linux (GNU sed): バックアップ不要な場合 $ sed -i 's/old/new/' ファイル名 # macOS (BSD sed): バックアップ不要な場合でも空文字が必須 $ sed -i '' 's/old/new/' ファイル名

本記事のまとめ(sed早見表)

やりたいこと コマンド
文字列を置換する(各行最初の1つ) sed 's/検索/置換/' ファイル名
文字列をすべて置換する sed 's/検索/置換/g' ファイル名
ファイルを直接書き換える(バックアップ付き) sed -i.bak 's/検索/置換/g' ファイル名
特定の行だけ置換する sed '5s/検索/置換/' ファイル名
行範囲を指定して置換する sed '10,20s/検索/置換/g' ファイル名
パターンにマッチした行を削除する sed '/パターン/d' ファイル名
コメント行を削除する sed '/^#/d' ファイル名
空行を削除する sed '/^$/d' ファイル名
コメントアウトする sed -i.bak '/パターン/s/^/#/' ファイル名
特定の行だけを表示する sed -n '10,20p' ファイル名
複数の操作を同時に実行する sed -e 's/old/new/g' -e '/^$/d' ファイル名
設定値を一括で書き換える sed -i 's/^設定名=.*/設定名=新しい値/' ファイル名
日付形式を変換する(後方参照) sed 's/\([0-9]\{4\}\)-\([0-9]\{2\}\)/\1\//g' ファイル名
拡張正規表現を使う sed -E 's/パターン/置換後/g' ファイル名
Windows の CR( )を削除する sed -i 's/ //' ファイル名
行の前にテキストを挿入する sed '/パターン/i\挿入テキスト' ファイル名
行の後にテキストを追加する sed '/パターン/a\追加テキスト' ファイル名
複数ファイルを一括置換する(find) find パス -name "*.conf" -exec sed -i.bak 's/検索/置換/g' {} \;
複数ファイルを一括置換する(xargs) find パス -name "*.conf" | xargs sed -i.bak 's/検索/置換/g'

設定ファイル管理を自動化・効率化したい方へ

sed を使いこなせると、サーバー構築・設定変更のスピードが劇的に上がります。
ネットの切れ端の情報をコピペするだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、'Linuxサーバー構築入門マニュアル(図解60P)'を完全無料でプレゼントしています。

「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。

===== EXCERPT (entry_excerpt) ===== sedコマンドで文字列を置換する方法を実行例付きで解説。基本構文(s/検索/置換/g)から-iオプションによるファイル直接書き換え、正規表現・後方参照の活用、find/xargsを使った複数ファイルの一括置換手順まで網羅しました。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

登録10秒/合わなければ解除3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。