sedコマンド:文字列の置換、行の削除と-iオプションの使い方

テスト環境RHEL系AlmaLinux 9.8rootアカウント2026-10-28 確認

sedコマンドは、ファイルの内容を1行ずつ読み、置換・削除・挿入を実行するLinuxのツールで、エディターを開かずに設定ファイルの値を変更できます。AlmaLinux 9サーバーでWordPressのwp-config.phpのコピーにsedを実行した結果、-i.bakで元のファイルを残したままデータベース名を変更できました。

記事に載せたエラーメッセージは、英語のlocaleで出力したそのままのものです。

1️⃣ sedコマンドの基本的な使い方とs置換

最もよく使うsコマンドは、[s/検索文字列/置換文字列/]の形式で文字列を置換します。1行の中で最初に見つかった1つだけを置換します。

echo 'http://example.com http://example.com/blog' | sed 's/http:/https:/'
https://example.com http://example.com/blog

行内のすべての文字列を置換するには、末尾にgフラグを付けます。

echo 'http://example.com http://example.com/blog' | sed 's/http:/https:/g'
https://example.com https://example.com/blog

ファイル名を後ろに付けると、そのファイルを読んで置換した結果を出力します。WordPressのwp-config-sample.phpをwp-config.phpとしてコピーしたファイルでDB_USERの値を変更し、grepでその行だけを確認しました。

sed 's/username_here/wp_user/' wp-config.php | grep DB_USER
define( 'DB_USER', 'wp_user' );

出力で値が変わったのでファイルも変わったと思いがちですが、sedはオプションなしで実行すると結果を画面に出力するだけで、元のファイルはそのまま残します。同じ行をファイルで探し直すと、最初の値がそのまま残っていました。

grep DB_USER wp-config.php
define( 'DB_USER', 'username_here' );

元のファイルまで変更するには、4️⃣の-iオプションを使います。

2️⃣ sedの行番号とパターンで行を選ぶ(-n、p)

sコマンドはアドレスなしで実行するとすべての行に適用されるため、特定の行だけを扱うには、コマンドの前に行番号やパターンをアドレスとして書きます。-nは自動出力をオフにし、pは選んだ行を出力します。2つを一緒に使うと23行目だけが表示されます。

sed -n '23p' wp-config.php
define( 'DB_NAME', 'database_name_here' );

カンマで2つの行番号をつなぐと、その範囲が表示されます。23行目から32行目までは、データベース名とユーザー、パスワード、ホストの設定が入っている区間です。

sed -n '23,32p' wp-config.php
define( 'DB_NAME', 'database_name_here' );

/** Database username */
define( 'DB_USER', 'username_here' );

/** Database password */
define( 'DB_PASSWORD', 'password_here' );

/** Database hostname */
define( 'DB_HOST', 'localhost' );

行番号の代わりにスラッシュの間にパターンを書くと、そのパターンを含む行をすべて選びます。

sed -n '/DB_/p' wp-config.php
define( 'DB_NAME', 'database_name_here' );
define( 'DB_USER', 'username_here' );
define( 'DB_PASSWORD', 'password_here' );
define( 'DB_HOST', 'localhost' );
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', '' );

[=]コマンドは選んだ行の番号を出力します。アドレス$は最後の行を意味するので、[$=]でファイル全体の行数を確認できます。

sed -n '/DB_HOST/=' wp-config.php
32
sed -n '$=' wp-config.php
102

アドレスはsコマンドの前にも付けられます。以下は32行目だけでlocalhostを変更し、pフラグで変更された行だけを出力した結果です。

sed -n '32s/localhost/127.0.0.1/p' wp-config.php
define( 'DB_HOST', '127.0.0.1' );

-nなしでpを実行すると、選んだ行がもう一度表示されました。sedは行を1つずつパターンスペースに読み込んでコマンドを実行した後、パターンスペースを自動で出力するため、pで出力した2行目が自動出力でもう一度表示されます。

sed '2p' wp-config.php | head -n 4
<?php
/**
/**
 * The base configuration for WordPress

行を1つずつ読んで処理するこの方式は、工場のベルトコンベアが部品を1つずつ作業台に載せて加工し、次の部品へ移るのと同じです。

コマンドによって行ごとに何が出力されるかは、以下の図で順に比較できます。

🧭 sedのパターンスペースと自動出力:2行目にp、d
解説ダイアグラム
⚙️ コマンド
$ sed '2p'-n '2p''2d' wp-config.php
読んだ行コマンドの実行と出力
1行目 → パターンスペース<?php
➜
アドレス2と異なる:コマンドなし自動出力1回-nなので出力なし
2行目 → パターンスペース/**
➜
アドレス2と一致:pを実行アドレス2と一致:dを実行pで1回 + 自動出力1回pで1回だけ出力パターンスペースを消して次の行へ
3行目 → パターンスペース * The base configuration for WordPress
➜
アドレス2と異なる:コマンドなし自動出力1回-nなので出力なし
🖥️ 画面に出力されるもの(1~3行目)
<?php/**/** * The base configuration for WordPress
pはパターンスペースをもう一度出力するコマンドなので、-nなしで実行すると2行目が2回出力されます。
-nは自動出力をオフにするので、pで選んだ2行目だけが1回出力されます。
dはパターンスペースを消して次の行へ進むので、2行目は自動出力されません。

3️⃣ sedコマンドの行削除と挿入(d、i、a)

dは選んだ行を削除するコマンドです。以下のnginx設定サンプルからコメント行を除いて見るには、#で始まる行や#の前に空白しかない行を[^ *#]パターンで選びます。

cat example.conf
# example.com
server {
    listen 80;
    server_name example.com www.example.com;

    # document root
    root /var/www/example.com;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}
sed '/^ *#/d' example.conf
server {
    listen 80;
    server_name example.com www.example.com;

    root /var/www/example.com;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

セミコロンでコマンドをつなぐと、空行を意味する[^$]まで一緒に削除します。コメント行を削除した結果に残っていた空行2つが消え、設定の行だけが残りました。

sed '/^ *#/d; /^$/d' example.conf
server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com;
    index index.php index.html;
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

iは選んだ行の前に、aは選んだ行の後に文字を挿入します。1行目の前にコメントを1行挿入した結果は以下のとおりです。

sed '1i # managed by sed' example.conf | head -n 3
# managed by sed
# example.com
server {

aの後にインデントした文字を書くとインデントも一緒に入ると思いがちですが、GNU sedはaの直後の空白を読み飛ばして文字だけを挿入します。

sed '/index index.php/a    client_max_body_size 64M;' example.conf
# example.com
server {
    listen 80;
    server_name example.com www.example.com;

    # document root
    root /var/www/example.com;
    index index.php index.html;
client_max_body_size 64M;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

インデントを保つには、aの後にバックスラッシュを付けます。バックスラッシュの後の空白から文字として入ります。

sed '/index index.php/a\    client_max_body_size 64M;' example.conf
# example.com
server {
    listen 80;
    server_name example.com www.example.com;

    # document root
    root /var/www/example.com;
    index index.php index.html;
    client_max_body_size 64M;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }
}

cは選んだ行を丸ごと置き換えるコマンドです。以下はlisten 80の行を8080に変更した結果の先頭4行です。

sed '/listen 80;/c\    listen 8080;' example.conf | head -n 4
# example.com
server {
    listen 8080;
    server_name example.com www.example.com;

4️⃣ sed -iによるファイルの直接編集とバックアップファイル名

-iは結果を画面ではなく元のファイルに保存するオプションです。-iのすぐ後に付けた文字はバックアップファイル名の末尾に付きます。 wp-config.phpのようにサイトが読むファイルは、-i.bakで元のファイルを残してから編集します。

cp wp-config-sample.php wp-config.php
sed -i.bak 's/database_name_here/wordpress_db/' wp-config.php

-iで実行すると画面には何も出力されないので、ls -lでファイルを確認します。

ls -l wp-config.php*
-rw-r--r-- 1 root root 3333 Oct 28 15:13 wp-config.php
-rw-r--r-- 1 root root 3339 Oct 28 15:13 wp-config.php.bak

編集したファイルと.bakファイルが一緒にできました。database_name_hereがwordpress_dbに短くなった分、サイズが6バイト小さくなりました。diffで2つのファイルを比較すると、変更された行だけを確認できます。

diff wp-config.php.bak wp-config.php
23c23
< define( 'DB_NAME', 'database_name_here' );
---
> define( 'DB_NAME', 'wordpress_db' );

変更された行は23行目のDB_NAMEの1行です。

変更する値が複数あるときは、-eでスクリプトをつないで一度に実行します。

sed -i -e 's/username_here/wp_user/' -e 's/password_here/wp_pass/' wp-config.php
grep -n -e DB_USER -e DB_PASSWORD wp-config.php
26:define( 'DB_USER', 'wp_user' );
29:define( 'DB_PASSWORD', 'wp_pass' );

-iと-eを[-ie]のように続けて書くと、eまでバックアップ名として読まれ、以下のようにwp-config.phpeファイルができました。

sed -ie 's/127.0.0.1/localhost/' wp-config.php
ls wp-config.php*
wp-config.php
wp-config.php.bak
wp-config.phpe

-iは編集した内容を新しいファイルに書いてから元の名前に置き換えるため、実行前後でファイルのinode番号が変わります。

ls -i wp-config.php
207618887 wp-config.php
sed -i 's/localhost/127.0.0.1/' wp-config.php
ls -i wp-config.php
207618883 wp-config.php

実行前に207618887だったinode番号が207618883に変わりました。

ファイルがないかファイル名を書き忘れると、以下のエラーで終わり、どのファイルも変更されません。

sed -i 's/x/y/' no-such.php
sed: can't read no-such.php: No such file or directory
sed -i 's/x/y/'
sed: no input files

5️⃣ sedコマンドの正規表現、区切り文字の変更とオプション

🔲 正規表現と区切り文字の変更

パスのようにスラッシュを含む値を変更すると、sコマンドの区切り文字と値のスラッシュが混ざるため、値のスラッシュごとにバックスラッシュを付ける必要があります。

sed -n 's/\/var\/www\/example.com/\/srv\/www\/example.com/p' example.conf
    root /srv/www/example.com;

sのすぐ後の文字が区切り文字になるので、値に含まれない|に変えると、バックスラッシュなしで同じ結果になります。

sed -n 's|/var/www/example.com|/srv/www/example.com|p' example.conf
    root /srv/www/example.com;

パターンのドット(.)は任意の1文字に一致します。以下はexample.comを探すパターンがexampleXcomまで変更した結果です。

echo 'exampleXcom example.com' | sed 's/example.com/test.org/g'
test.org test.org

ドットを文字どおりに探すには、前にバックスラッシュを付けます。

echo 'exampleXcom example.com' | sed 's/example\.com/test.org/g'
exampleXcom test.org

かっこで囲んだ部分は、置換文字列で[\1]として呼び出します。-Eを付けると、かっこと+をバックスラッシュなしで使えます。以下はlistenの後の数字をそのままにしてdefault_serverを追加した結果です。

sed -nE 's/listen ([0-9]+);/listen \1 default_server;/p' example.conf
    listen 80 default_server;

-Eなしで同じスクリプトを実行すると、かっこを文字として読むため、呼び出すグループがないというエラーになります。-Eなしで使うには、かっこと+にバックスラッシュを付けます。

sed -n 's/listen ([0-9]+);/listen \1 default_server;/p' example.conf
sed: -e expression #1, char 46: invalid reference \1 on `s' command's RHS
sed -n 's/listen \([0-9]\+\);/listen \1 default_server;/p' example.conf
    listen 80 default_server;

置換文字列の[&]はパターンに一致した文字全体を意味するので、一致した部分の前に#を付けて、その行をコメントにできます。

sed -n 's/server_name .*;/# &/p' example.conf
    # server_name example.com www.example.com;

🔲 sedコマンドのオプション

📌 主なオプション: この記事で実行した結果

オプション作業この記事で確認した結果
-n自動出力をオフにしてpで選んだ行だけを出力sed -n '23p'で23行目の1行だけが表示、-nなしの2pは2行目が2回
-i結果を画面ではなく元のファイルに保存(すぐ後の文字はバックアップ名の末尾に付く)-i.bakでwp-config.php.bakができる、実行後にinode番号が変わる
-e複数のスクリプトをつないで一度に実行DB_USERとDB_PASSWORDの2つの値が一度に変わる、-ieと続けるとwp-config.phpeのバックアップができる
-E拡張正規表現を使用(かっこと+にバックスラッシュなし)listen 80 default_server;を出力、-Eなしの同じスクリプトは[invalid reference]エラー
--follow-symlinks-iと一緒に使い、リンクが指す元のファイルを編集なければリンクの位置に通常のファイルができ元のファイルはそのまま、付けると元の値が変わる

📎 その他のオプション: 公式マニュアルより

オプション作業
-fスクリプトをファイルから読んで実行
-r-Eと同じ拡張正規表現(移植性は-E)
-s複数のファイルを連続した1つではなくファイルごとに別々に処理
-z行を改行の代わりにヌル文字で区切る
-u入力を少しずつ読み、出力をより頻繁に送り出す
--posixGNU拡張機能をすべてオフにする
--debug実行過程を展開して出力

🔲 sedコマンドシミュレーター

以下のシミュレーターの作業フォルダーには、wp-config.phpのコピーとexample.confがあります。これまでのコマンドを実際に入力し、-iで変更されたファイルはls -lとdiffで確認できます。

sedコマンドシミュレーターGNU sed
[root@server work]#
キーボードの↑↓で、前に入力したコマンドを呼び出せます。

🔢 FAQ & おすすめコンテンツ

WordPressのwp-config-sample.phpは行末がCRLFなので、行末の直前に見えない[\r]があります。[/false );$/]では1行も出力されず、[s/\r$//]で[\r]を消したコピーでは同じパターンがWP_DEBUGの行を見つけました。

-iはリンクの位置に通常のファイルを新しく作って保存するので、リンクが指していた元のファイルは変わりませんでした。元のファイルを編集するには[--follow-symlinks]を一緒に指定します。このときはリンクがそのまま残り、元の値が変わりました。

NEW=wp_userで入れておいた変数も、シングルクォートの中に書くとシェルが展開しないので、[$NEW]が文字どおり入ります。スクリプトをダブルクォートで囲むとシェルが変数を先に展開し、[$NEW]の位置にwp_userが入りました。

🧭 テキストコマンドのおすすめコンテンツ 記事9・参照2
🗂️ テキスト表示・編集コマンド
📄 grepコマンド 📄 sortコマンド 📄 uniqコマンド 📄 teeコマンド 📄 sedコマンド
📄 catコマンド 📄 lessコマンド 📄 head・tailコマンド 📄 vi・vimコマンド

ℹ️ 提携について
当サイトのコンテンツにはアフィリエイトリンクが含まれています。訪問者がこのリンクを通じて商品やサービスを購入すると、当サイトは販売元から手数料を受け取ります。この過程において、購入者が支払う金額(イベント割引適用で金額が下がります↓)は上昇しません。掲載されている価格・割引・在庫情報は作成時点のものであり、実際とは異なる場合がありますので、ご購入前に販売元にて最終確認をお願いいたします。商品の選定および評価は独自の基準に基づいて行われており、手数料の支払いの有無は紹介順や評価内容に影響を与えません。

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

人間であることを証明してください: 6   +   9   =