【Linux】sedコマンドの使い方と文字列置換完全ガイド|-i上書き・正規表現・行削除の逆引き早見表

コマンドリファレンス

こんにちは、Bash玄(ばっしゅげん)です。

サーバー構築やスクリプト開発、日々のログ調査で「設定ファイルのIPアドレスやドメインを一括置換したい」「ログから不要なコメント行や空行を一瞬で削りたい」という場面は日常茶飯事です。手作業でエディタを開いて1行ずつ修正するのは時間の浪費であり、オペレーションミスの原因にもなります。「手作業は負け」、これらはすべてコマンド1行で自動化するのが鉄則です。

テキスト加工の自動化において、最も基本かつ強力な武器が sed(stream editor)コマンドです。この記事では、基本構文から主要オプション一覧、さらに 実務で即使える文字列置換・ファイル直接上書き(-i)・行削除・正規表現グループ参照・Mac(BSD sed)との挙動の違い まで、逆引き早見表付きで徹底解説します。

【3秒で解決】実務頻出sedコマンド逆引き早見表

  • 文字列を一括置換(全置換): sed 's/置換前/置換後/g' file.txt
  • 元ファイルを直接上書き保存: sed -i 's/置換前/置換後/g' file.txt
  • バックアップを作成して上書き: sed -i.bak 's/置換前/置換後/g' file.txt
  • URLやパスを置換(区切り文字変更): sed 's#http://#https://#g' file.txt
  • 特定文字列を含む行を削除: sed '/削除パターン/d' file.txt
  • 空行・コメント行を一括削除: sed -e '/^#/d' -e '/^$/d' file.txt
  • 指定した行範囲のみ抽出表示: sed -n '10,20p' file.txt
  • 拡張正規表現でグループ参照置換: sed -E 's/([0-9]{4})-([0-9]{2})/1/2/g' file.txt

sedコマンドの基本構文と主要オプション早見表

基本書式: sed [オプション] ‘スクリプト’ [入力ファイル]

sed(Stream Editor)は、入力されたテキストストリームを1行ずつ読み込み、指定したスクリプト(編集命令)に従って加工した結果を標準出力に書き出すコマンドラインツールです。

# 基本書式
sed [オプション] '編集コマンド' [対象ファイル]

# パイプから標準入力を受け取る場合
cat input.txt | sed '編集コマンド'
command_output | sed '編集コマンド'

sed はデフォルトでは 元ファイルを一切変更せず、変換結果のみを標準出力(画面)に出力 します。そのため、本番環境の設定ファイルや重要なログでも、まずは安全に置換結果を確認できるのが大きなメリットです。

よく使うオプション早見表(-i, -e, -n, -E)

実務で頻出する sed の主要オプションを整理しました。これら 4つ を押さえておけば、日常業務の9割以上のテキスト処理に対応できます。

オプション機能・効果実務での実用例
-i[拡張子]元ファイルを直接上書き保存(in-place編集)sed -i 's/foo/bar/g' app.conf
-e複数の編集スクリプトを連続して指定・実行sed -e '/^#/d' -e '/^$/d' nginx.conf
-n各行の自動出力を抑制(p コマンドと併用して特定行を抽出)sed -n '10,20p' /var/log/syslog
-E(または -r拡張正規表現(ERE: +, ?, (), | 等)を有効化sed -E 's/[0-9]+/NUM/g' data.txt
-f外部スクリプトファイルから編集ルールを読み込んで実行sed -f rules.sed target.txt

文字列置換の実務パターン(sコマンド)

sed で最も頻繁に使用するのが文字列置換を行う s(substitute)コマンドです。基本構文と実務頻出の活用テクニックをマスターしましょう。

基本の文字列置換(s/before/after/g)

基本書式は s/置換前/置換後/フラグ です。末尾のフラグによって置換の挙動が変わります。

# ① 最初に見つかった文字列のみ置換(フラグなし)
echo "apple banana apple" | sed 's/apple/orange/'
# 出力: orange banana apple

# ② 行内のすべての一致文字列を一括置換(gフラグ: global)
echo "apple banana apple" | sed 's/apple/orange/g'
# 出力: orange banana orange

# ③ 大文字・小文字を区別せずに置換(Iフラグ: ignore-case ※GNU sed)
echo "ERROR error Error" | sed 's/error/[WARN]/gI'
# 出力: [WARN] [WARN] [WARN]

# ④ 特定の行番号のみ置換(例: 2行目のみ)
sed '2s/localhost/127.0.0.1/' hosts.txt

# ⑤ 特定の行範囲のみ置換(例: 10行目から20行目まで)
sed '10,20s/disable/enable/g' app.conf

実務で「行内のすべての文字列を変えたい」場合は、必ず末尾に g フラグを付与することを忘れないでください。g を付け忘れると、各行の 1箇所目 しか置換されず、バグの原因になります。

元ファイルを直接上書き保存する(-i オプションとバックアップ作成)

置換結果をターミナルに表示するだけでなく、ファイルそのものを直接書き換えるには -i(in-place)オプションを使用します。

# 1. まずは画面に出力して置換内容が正しいか安全確認
sed 's/SERVER_PORT=80/SERVER_PORT=8080/g' server.conf

# 2. 確認後、元ファイルを直接上書き保存(Linux GNU sed)
sed -i 's/SERVER_PORT=80/SERVER_PORT=8080/g' server.conf

# 3. バックアップファイル(server.conf.bak)を作成して上書き保存(推奨!)
sed -i.bak 's/SERVER_PORT=80/SERVER_PORT=8080/g' server.conf

本番環境の設定変更では、「まず -i なしで確認 → -i.bak でバックアップ付き上書き実行」 を徹底するのが、システム運用における鉄壁の安全手順です。

パスやURLを含む場合の区切り文字変更(s#http://#https://#g)

URLやディレクトリパスなど、置換文字列の中にスラッシュ / が含まれている場合、標準の区切り文字 / のままだとすべてバックスラッシュでエスケープ(/)しなければならず、可読性が極端に悪化(いわゆる「つまようじ地獄」)します。

sed では、s コマンドの直後の文字を任意のデリミタ(区切り文字)として使用できます。実務では #@|% を使うのが一般的です。

# ✕ 可読性が悪くミスしやすい書き方(エスケープ地獄)
sed 's/http://example.com/api/v1/https://example.com/api/v2/g' app.env

# ◯ デリミタに「#」を使用したクリーンで安全な書き方
sed 's#http://example.com/api/v1#https://example.com/api/v2#g' app.env

# ◯ デリミタに「@」を使用したディレクトリパスの置換例
sed 's@/var/www/html@/usr/share/nginx/html@g' default.conf

拡張正規表現を使ったグループ参照置換(-E と 1, 2)

-E(または -r)オプションを併用すると、拡張正規表現(ERE)が利用可能になります。丸かっこ ( ) でグループ化した部分を、置換後文字列の中で 12 として後方参照(キャプチャ参照)できます。

# 日付フォーマットの変換(YYYY-MM-DD → YYYY/MM/DD)
echo "Date: 2026-09-13" | sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/1/2/3/'
# 出力: Date: 2026/09/13

# キー・バリューの順序を入れ替える
echo "user=tanaka" | sed -E 's/([^=]+)=(.+)/2 (1)/'
# 出力: tanaka (user)

# ログからIPアドレスとタイムスタンプのみを再構成して抽出
echo "2026-09-13 12:00:00 [INFO] 192.168.1.10 login success" | 
  sed -E 's/^([0-9-]+ [0-9:]+) .* ([0-9]+.[0-9]+.[0-9]+.[0-9]+) .*/2 - [1]/'
# 出力: 192.168.1.10 - [2026-09-13 12:00:00]

行の削除・抽出・挿入パターン

sed の強みは文字列置換だけではありません。行単位での「削除(d)」「抽出(p)」「先頭・末尾への文字挿入」も高速に処理できます。

特定の文字列を含む行を削除する(/pattern/d)

末尾に d(delete)コマンドを指定することで、パターンに一致した行をまるごと削除して出力できます。

# ① 「DEBUG」または「INFO」を含む行を削除してエラーのみ残す
sed '/DEBUG/d' app.log

# ② 1行目(ヘッダー行)を削除(CSVデータの前処理に最適)
sed '1d' users.csv

# ③ 最終行(フッター行)を削除($d)
sed '$d' data.txt

# ④ 指定した行番号の範囲(例: 1行目〜5行目)を削除
sed '1,5d' input.txt

空行やコメント行を一括削除する

Linuxの設定ファイル(nginx.confssh_config 等)を調査する際、膨大なコメント行や空行が邪魔で実質的な設定が見えにくいことがよくあります。sed を使えば有効行だけを一瞬で抜き出せます。

# 空行を削除(行頭^と行末$が直結する行)
sed '/^$/d' config.txt

# コメント行(#で始まる行)を削除
sed '/^#/d' config.txt

# 空白文字(スペースやタブ)のみの空行も含めて削除
sed '/^[[:space:]]*$/d' config.txt

# 【決定版】コメント行と空行を同時に一掃し、有効設定行のみ表示
sed -e '/^[[:space:]]*#/d' -e '/^[[:space:]]*$/d' /etc/nginx/nginx.conf

指定した行番号の範囲だけを表示する(sed -n ‘10,20p’)

-n オプションでデフォルトの行出力を抑制し、p(print)コマンドを組み合わせることで、条件に一致した行だけをピンポイントで抽出できます。

# 10行目から20行目までの範囲を抽出表示
sed -n '10,20p' /var/log/syslog

# 5行目だけをピンポイント表示
sed -n '5p' target.txt

# 特定パターンを含む行のみを抽出(grepと同様の動作)
sed -n '/[FATAL]/p' app.log

# 「START」から「END」で囲まれたブロック行のみを抽出
sed -n '/START/,/END/p' server.log

行の先頭・末尾への文字挿入・追加(^, $ の置換)

正規表現の行頭記号 ^ や行末記号 $ を置換対象にすることで、すべての行の先頭や末尾に任意の文字列を一括追加できます。

# 全行の先頭に「# 」を追加(設定ファイルの一括コメントアウト)
sed 's/^/# /' hosts.allow

# 全行の先頭にインデント(スペース4個)を追加
sed 's/^/    /' snippet.py

# 全行の末尾にカンマ「,」を追加(リストや配列定義用)
sed 's/$/,/' id_list.txt

# 全行の末尾にセミコロン「;」を追加
sed 's/$/;/' query_list.sql

Mac(BSD sed)とLinux(GNU sed)の挙動の違いと対策

ローカル開発環境が macOS で本番サーバーが Linux(Ubuntu / RHEL 等)の場合、sed の実装差異によってスクリプトがエラー停止するトラブルが頻発します。

sed -i のバックアップ拡張子指定の罠(Mac: sed -i ” vs Linux: sed -i)

最大の落とし穴が ファイル上書きオプション -i の引数仕様の違い です。

環境実装バックアップなしの書き方バックアップありの書き方
Linux(Ubuntu, RHEL等)GNU sedsed -i 's/a/b/g' filesed -i.bak 's/a/b/g' file
macOS(標準環境)BSD sedsed -i '' 's/a/b/g' filesed -i .bak 's/a/b/g' file

macOS(BSD sed)で sed -i 's/a/b/g' file.txt を実行すると、次のようなエラーが発生します:

# macOSでLinux流の書き方を実行した場合のエラー
sed: 1: "file.txt": invalid command code f

BSD sed では -i の直後に「バックアップ拡張子」が必須となっており、拡張子を省略したい場合は空文字 '' を明示的に渡す必要があります。しかし、この sed -i '' を Linux(GNU sed)で実行すると、今度は '' をスクリプト本体と解釈してエラーになります。

【解決策1】OSを問わず動く共通の書き方(バックアップ作成)
最もシンプルで安全な解決策は、拡張子を直結させた -i.bak を使うことです。これは Linux でも macOS でも共通して正常に動作します。

# Linux / macOS 両対応の安全なワンライナー
sed -i.bak 's/old/new/g' file.txt && rm file.txt.bak

【解決策2】シェルスクリプト内でのOS判定ラッパー
チーム開発やCI/CDパイプラインでバックアップファイルを残さずに処理したい場合は、スクリプト内でOSを自動判定します。

# OS自動判定ラッパースクリプト例
if [[ "$OSTYPE" == "darwin"* ]]; then
  sed_inplace=(-i '')
else
  sed_inplace=(-i)
fi

sed "${sed_inplace[@]}" 's/old/new/g' target.txt

実務で差がつく応用スクリプト連携

日々の現場業務で劇的な効率化をもたらす、他のコマンドとの連携パターンを紹介します。

find × xargs と連携した複数ファイルの一括置換

ディレクトリ配下の複数の設定ファイルやソースコードを横断して文字列を一括置換したい場合は、findxargs をパイプで連携します。

# カレントディレクトリ配下のすべての .conf ファイルを一括置換
find . -type f -name "*.conf" -print0 | xargs -0 sed -i 's/example.org/example.com/g'

# 特定ディレクトリ(src/)内の .py ファイルの旧APIエンドポイントを一括更新
find src/ -type f -name "*.py" -print0 | xargs -0 sed -i 's#/api/v1/#/api/v2/#g'

ファイル名にスペースが含まれている場合でも安全に処理できるよう、find -print0xargs -0(Null文字区切り)を併用するのがインフラ現場の鉄則です。

Bash変数を含む動的置換(ダブルクォート囲み)

シェル変数(環境変数)を展開して置換したい場合、シングルクォート '...' で囲むと展開されません。必ず 外側をダブルクォート "..." で囲む 必要があります。

NEW_IP="192.168.11.200"
CONFIG_FILE="/etc/app/network.conf"

# ✕ シングルクォートだと $NEW_IP という文字がそのまま書き込まれる
sed -i 's/HOST_IP=.*/HOST_IP=$NEW_IP/' "$CONFIG_FILE"

# ◯ ダブルクォートで変数を展開
sed -i "s/HOST_IP=.*/HOST_IP=${NEW_IP}/" "$CONFIG_FILE"

# 変数にスラッシュ「/」が含まれる場合は代替デリミタ「#」を併用
API_URL="https://api.example.com/v3"
sed -i "s#BASE_URL=.*#BASE_URL=${API_URL}#" "$CONFIG_FILE"

まとめ & 関連記事

sed コマンドの重要ポイントを整理します:

  • 基本は s/置換前/置換後/g:まずは -i なしで画面出力して安全確認する。
  • 元ファイル上書きは -i(推奨は -i.bak:macOS(BSD sed: -i '')と Linux(GNU sed: -i)の引数仕様の違いに注意する。
  • パスやURLは代替デリミタ(#@:エスケープの連続を排除して可読性と保守性を高める。
  • 行削除は /pattern/d、範囲抽出は sed -n '10,20p':テキスト抽出・整形もコマンド1行で完結する。

Linuxでのテキスト処理やスクリプト自動化のスキルをさらに高めたい方は、以下の関連コマンド解説やピラー記事もぜひご参照ください。

関連コマンド&ピラー記事

Bash玄

はじめまして!Bash玄です。

エンジニアとしてシステム運用に携わる中で、手作業の多さに限界を感じ、Bashスクリプトを活用して業務を効率化したのがきっかけで、この道に入りました。「手作業は負け」「スクリプトはシンプルに」をモットーに、誰でも実践できるBashスクリプトの書き方を発信しています。

このサイトでは、Bashの基礎から実践的なスクリプト作成まで、初心者でもわかりやすく解説しています。少しでも「Bashって便利だな」と思ってもらえたら嬉しいです!

# 好きなこと
- シンプルなコードを書くこと
- コマンドラインを快適にカスタマイズすること
- 自動化で時間を生み出すこと

# このサイトを読んでほしい人
- Bashに興味があるけど、何から始めればいいかわからない人
- 定型業務を自動化したい人
- 効率よくターミナルを使いこなしたい人

Bashの世界に一歩踏み出して、一緒に「Bash道」を極めていきましょう!

Bash玄をフォローする

コメント