【完全リファレンス】Linux sedコマンドのオプション一覧と使い方|実用例80超で徹底解説

【完全リファレンス】Linux sedコマンドのオプション一覧と使い方|実用例80超で徹底解説

sed(stream editor)はLinuxでテキスト変換・加工に最もよく使われるコマンドのひとつで、ファイルの一括置換からログ整形、シェルスクリプトでの自動処理まで、エンジニアの日常作業に欠かせないツールです。しかし、

  • 置換の基本は分かるが応用になると書き方を忘れる
  • -i でファイルを直接書き換えるのが怖い
  • アドレス指定(行番号・正規表現)の書き方が複雑
  • 複数のコマンドを組み合わせる方法が分からない
  • macOSで動かない -i の挙動の違い
  • 改行をまたいだ置換をしたい
  • awktr との使い分けが分からない

など、使いこなしには知識が必要です。

本記事では、sedコマンドの全主要オプションと実用パターンを、リファレンスとしてまとめました。基本置換から正規表現・アドレス指定・マルチライン処理・スクリプトファイル、macOSとの違い、80超の実用例、FAQまで完全網羅。この1本をブックマークすれば、sedに関するあらゆる疑問が解決します。


目次

結論:今すぐ使える基本パターン5選

時間がない方向けに、超頻出パターンを先に示します。

# ① 文字列を置換して出力
sed 's/ERROR/WARNING/' application.log

# ② ファイルを直接書き換え(バックアップ付き)
sed -i.bak 's/old/new/g' config.txt

# ③ 特定の行を削除
sed '/^#/d' config.txt

# ④ 特定行の範囲だけ処理
sed '10,20s/foo/bar/g' file.txt

# ⑤ 複数コマンドを一度に実行
sed -e 's/ERROR/WARNING/g' -e 's/FATAL/CRITICAL/g' application.log

詳細・応用は以下で順に解説します。


sedコマンドの基本構文

sed [オプション] 'コマンド' [ファイル...]
sed [オプション] -f スクリプトファイル [ファイル...]

最もシンプルな例

# ファイルの内容を置換して標準出力に表示
sed 's/foo/bar/' file.txt

# 標準入力から処理
cat file.txt | sed 's/foo/bar/'
echo "Hello World" | sed 's/World/sed/'

# 複数ファイルを処理
sed 's/foo/bar/' file1.txt file2.txt file3.txt

出力の仕組み

sedはデフォルトで処理結果を標準出力に出力し、元ファイルは変更しません。

# 元ファイルは変わらない
sed 's/foo/bar/' file.txt
cat file.txt  # 変更されていない

# ファイルを書き換えるには -i
sed -i 's/foo/bar/' file.txt

主要オプション一覧表

動作制御オプション

オプション説明
-n自動出力を抑制(pコマンドと組み合わせて使う)
-e スクリプトコマンドをインラインで指定(複数指定可)
-f ファイルスクリプトをファイルから読み込み
-i[拡張子]ファイルをインプレース編集(直接書き換え)
-E / -r拡張正規表現(ERE)を使用
-s複数ファイルを個別に処理(行番号がファイルごとにリセット)
--sandbox安全モード(ファイル書き込み・外部コマンド実行を禁止)
--follow-symlinks-i 使用時にシンボリックリンクを追跡

sedコマンド(スクリプト内で使う命令)

コマンド説明
s/パターン/置換/フラグ置換
d行を削除
p行を出力(-n と組み合わせて使う)
q処理を終了(最初のN行だけ処理する際に有用)
Q処理を終了(現在行を出力しない)
a テキスト行の後にテキストを追加
i テキスト行の前にテキストを挿入
c テキスト行をテキストで置き換え
y/文字列1/文字列2/文字単位の変換(tr相当)
=現在の行番号を出力
r ファイルファイルの内容を読み込んで挿入
w ファイル出力をファイルに書き込む
n次の行を読み込む
N次の行をパターンスペースに追記
Dパターンスペースの最初の行を削除
Pパターンスペースの最初の行を出力
lパターンスペースを明示的に表示(制御文字も可視化)
zパターンスペースをクリア

置換フラグ(sコマンドのフラグ)

フラグ説明
g行内の全マッチを置換(デフォルトは最初の1件のみ)
N(数字)N番目のマッチのみ置換
p置換が行われた行を出力
w ファイル置換が行われた行をファイルに書き込む
i / I大文字小文字を無視(GNU sed)
e置換後の文字列をシェルコマンドとして実行(GNU sed)
m / Mマルチライン対応(^$を各行の先頭末尾に)

アドレス指定(処理対象行の絞り込み)

sedはデフォルト全行処理しますが、アドレスで対象行を絞れます。

行番号によるアドレス

# 5行目だけ処理
sed '5s/foo/bar/' file.txt

# 5行目から10行目まで
sed '5,10s/foo/bar/' file.txt

# 最終行($)
sed '$s/foo/bar/' file.txt

# 5行目から最終行まで
sed '5,$s/foo/bar/' file.txt

# 最終行を削除
sed '$d' file.txt

正規表現によるアドレス

# "ERROR"を含む行だけ処理
sed '/ERROR/s/foo/bar/' file.txt

# "START"から"END"までの範囲
sed '/START/,/END/s/foo/bar/' file.txt

# "ERROR"を含む行を削除
sed '/ERROR/d' file.txt

# "ERROR"を含まない行を削除(反転:!)
sed '/ERROR/!d' file.txt

アドレスの否定(!

# 1行目以外を削除(1行目だけ残す)
sed '1!d' file.txt

# コメント行以外に処理を適用
sed '/^#/!s/foo/bar/' file.txt

# 最終行以外を処理
sed '$!s/$/,/' file.txt  # 最終行以外の末尾にカンマを追加

ステップアドレス(GNU sed)

# 2行おきに処理(偶数行)
sed '0~2s/foo/bar/' file.txt

# 奇数行を処理
sed '1~2s/foo/bar/' file.txt

# 3行ごとに処理(3, 6, 9...行目)
sed '0~3s/foo/bar/' file.txt

置換(s コマンド)

sedで最も使われるコマンドです。

基本の置換

# 各行の最初のマッチを置換
sed 's/old/new/' file.txt

# 全マッチを置換(g フラグ)
sed 's/old/new/g' file.txt

# 大文字小文字を無視して置換(i フラグ)
sed 's/error/ERROR/gi' file.txt

# 2番目のマッチだけ置換
sed 's/foo/bar/2' file.txt

区切り文字の変更

スラッシュ以外を区切り文字に使えます。URLやパスを含む場合に便利。

# スラッシュを含むパスの置換(\ でエスケープが不要)
sed 's|/usr/local|/opt|g' config.txt
sed 's#/usr/local#/opt#g' config.txt
sed 's,/usr/local,/opt,g' config.txt

キャプチャグループと後方参照

# グループ化して順番を入れ替え(\1, \2 で参照)
echo "2026-06-17" | sed 's/\([0-9]\{4\}\)-\([0-9]\{2\}\)-\([0-9]\{2\}\)/\3\/\2\/\1/'
# → 17/06/2026

# 拡張正規表現ならエスケープ不要
echo "2026-06-17" | sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3\/\2\/\1/'

# マッチした部分を & で参照
echo "hello" | sed 's/hello/[&]/'
# → [hello]

# 単語をダブルクォートで囲む
echo "foo bar baz" | sed 's/[a-z]*/"&"/g'

正規表現を使った置換

# 行頭の空白を削除
sed 's/^[[:space:]]*//' file.txt

# 行末の空白を削除
sed 's/[[:space:]]*$//' file.txt

# 行頭・行末の空白を両方削除
sed 's/^[[:space:]]*//;s/[[:space:]]*$//' file.txt

# 複数の空白を1つに
sed 's/[[:space:]]\{2,\}/ /g' file.txt

# タブをスペースに
sed 's/\t/    /g' file.txt

-i でファイルを直接書き換え

# ファイルを直接書き換え
sed -i 's/foo/bar/g' file.txt

# バックアップを作りつつ書き換え(.bak ファイルが作成される)
sed -i.bak 's/foo/bar/g' file.txt

# 複数ファイルを一括書き換え
sed -i 's/v1\.0/v2\.0/g' *.conf

# ディレクトリ内の全 .py ファイルを書き換え
find . -name "*.py" -exec sed -i 's/old_api/new_api/g' {} +

⚠️ -i は元に戻せません。バックアップを取るか、まず -i なしで確認してから実行しましょう。


行の削除(d コマンド)

# 特定文字列を含む行を削除
sed '/ERROR/d' file.txt

# 空行を削除
sed '/^$/d' file.txt

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

# コメント行と空行を両方削除
sed '/^#/d;/^$/d' file.txt

# 特定行番号を削除
sed '5d' file.txt

# 先頭5行を削除
sed '1,5d' file.txt

# 最終行を削除
sed '$d' file.txt

# マッチした行の次の行を削除
sed '/PATTERN/{n;d}' file.txt

行の挿入・追加・置き換え(i / a / c コマンド)

# 5行目の前に挿入
sed '5i\新しい行' file.txt

# "PATTERN"を含む行の前に挿入
sed '/PATTERN/i\追加するテキスト' file.txt

# 5行目の後に追加
sed '5a\新しい行' file.txt

# 最終行の後に追加
sed '$a\最後に追加する行' file.txt

# "PATTERN"を含む行を別の文字列に置き換え
sed '/PATTERN/c\新しい行' file.txt

# 複数行を追加(\n で改行)
sed '/PATTERN/a\追加行1\n追加行2' file.txt

出力の制御(p コマンドと -n)

# マッチした行だけ出力(-n で自動出力を抑制)
sed -n '/ERROR/p' file.txt

# 特定行番号だけ出力
sed -n '5p' file.txt
sed -n '5,10p' file.txt

# 行番号付きで出力
sed -n '=' file.txt | paste - - -d: | head

# 最初の10行だけ出力(head の代わり)
sed -n '1,10p' file.txt

# 最初の10行で処理終了(より高速)
sed '10q' file.txt

# マッチした行とその行番号を表示
sed -n '/ERROR/{=;p}' file.txt

複数コマンドの書き方

-e でインライン指定

# 複数の置換
sed -e 's/ERROR/WARNING/g' -e 's/FATAL/CRITICAL/g' application.log

# 削除と置換の組み合わせ
sed -e '/^#/d' -e 's/foo/bar/g' file.txt

セミコロンで区切る

# セミコロンで複数コマンドを繋げる
sed 's/foo/bar/g;s/baz/qux/g' file.txt

# アドレスと組み合わせ
sed '/ERROR/d;/^$/d;s/WARNING/WARN/g' file.txt

-f スクリプトファイル

コマンドが多い場合はファイルにまとめると管理しやすくなります。

# script.sed の内容
/^#/d
/^$/d
s/ERROR/WARNING/g
s/localhost/127.0.0.1/g

# 実行
sed -f script.sed file.txt

文字変換(y コマンド)

yコマンドはtrと同様に1文字ずつ対応して変換します。

# 小文字を大文字に
sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' file.txt

# 大文字を小文字に
sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/' file.txt

# スラッシュをハイフンに
sed 'y/\//\-/' file.txt

trで十分な場合が多いですが、sedの処理の中で行単位に組み込める点が利点です。


正規表現(BRE と ERE)

BRE(デフォルト)

特殊文字(+, ?, |, (, {)をエスケープして使います。

# + のエスケープ
sed 's/[0-9]\+/NUM/' file.txt

# グループのエスケープ
sed 's/\(foo\)\(bar\)/\2\1/' file.txt

# 繰り返し回数
sed 's/[0-9]\{3\}/NUM/' file.txt

-E(拡張正規表現)

エスケープ不要になり、書きやすくなります。

# +, ?, |, (), {} がそのまま使える
sed -E 's/[0-9]+/NUM/' file.txt
sed -E 's/(foo)(bar)/\2\1/' file.txt
sed -E 's/https?:\/\///' file.txt
sed -E 's/ERROR|WARNING/ALERT/g' file.txt

よく使うメタ文字・文字クラス

パターン意味
.任意の1文字
*直前のパターンの0回以上の繰り返し
+直前のパターンの1回以上(BREは\+
?直前のパターンの0回または1回(BREは\?
^行頭
$行末
[abc]a, b, c のいずれか
[^abc]a, b, c 以外
\b単語境界(GNU sed)
[[:alpha:]]アルファベット
[[:digit:]]数字
[[:space:]]空白文字(スペース、タブ等)
[[:upper:]]大文字
[[:lower:]]小文字
[[:alnum:]]英数字

マルチライン処理(N / P / D)

sedは基本的に1行ずつ処理しますが、Nコマンドで複数行を扱えます。

# 2行を結合してから処理
sed 'N;s/\n/ /' file.txt

# 空行の連続を1行に圧縮
sed '/^$/{N;/^\n$/d}' file.txt

# 改行をまたいで置換("foo\nbar" → "foobar")
sed ':a;N;$!ba;s/\n//g' file.txt

# ファイル全体を1行にまとめる
sed ':a;N;$!ba;s/\n/ /g' file.txt

# BEGIN...END ブロックの間を削除
sed '/BEGIN/,/END/d' file.txt

:a;N;$!ba の解説

:a      # ラベル "a" を定義
N       # 次の行をパターンスペースに追記
$!ba    # 最終行でなければラベル "a" に戻る

ファイル全体をメモリに読み込む手法です。大きなファイルには不向き。


ホールドスペースの活用(h / H / g / G / x)

sedには「パターンスペース」(処理中の行)と「ホールドスペース」(一時保存用)があります。

コマンド説明
hパターンスペースをホールドスペースにコピー
Hパターンスペースをホールドスペースに追記
gホールドスペースをパターンスペースにコピー
Gホールドスペースをパターンスペースに追記
xパターンスペースとホールドスペースを交換
# ファイルを逆順に出力(tac の代わり)
sed -n '1!G;h;$p' file.txt

# 1行おきに空行を挿入
sed 'G' file.txt

# 前の行を参照して処理(連続する重複行を削除)
sed '$!N;/^\(.*\)\n\1$/!P;D' file.txt

実用パターン集(80超を厳選)

ファイル書き換え系

# 設定ファイルの値を変更
sed -i 's/^Port 22$/Port 2222/' /etc/ssh/sshd_config

# 環境変数ファイルを書き換え
sed -i 's/^DATABASE_HOST=.*/DATABASE_HOST=newhost/' .env

# バージョン番号を一括更新
sed -i 's/version="1\.0\.0"/version="2\.0\.0"/g' pom.xml

# Copyright年を更新
sed -i "s/Copyright 2025/Copyright 2026/g" *.py

# ハードコードされたURLを変更
sed -i 's|https://old-domain.com|https://new-domain.com|g' *.html

テキスト整形系

# 行頭の空白を削除(インデント削除)
sed 's/^[[:space:]]*//' file.txt

# 行末の空白を削除
sed 's/[[:space:]]*$//' file.txt

# 両端の空白を削除(trim)
sed 's/^[[:space:]]*//;s/[[:space:]]*$//' file.txt

# 空行を削除
sed '/^[[:space:]]*$/d' file.txt

# 連続する空行を1行に圧縮
sed '/^$/N;/^\n$/D' file.txt

# タブをスペース4つに変換
sed 's/\t/    /g' file.txt

# CSVの特定カラムを削除(2列目を削除)
sed 's/,[^,]*//' file.txt

# 行番号を付ける
sed = file.txt | sed 'N;s/\n/\t/'

ログ加工系

# タイムスタンプを除去して内容だけ抽出
sed 's/^[0-9-]\{10\} [0-9:]\{8\} //' application.log

# IPアドレスをマスク
sed -E 's/([0-9]{1,3}\.){3}[0-9]{1,3}/x.x.x.x/g' access.log

# Apache ログのレスポンスコードを抽出
sed -E 's/.* ([0-9]{3}) .*/\1/' access.log

# ログレベルを一括変換
sed 's/\[DEBUG\]/[D]/g;s/\[INFO\]/[I]/g;s/\[ERROR\]/[E]/g' app.log

# 特定日付以前のログを削除
sed '/^2025/d' application.log

# JSONログの特定フィールドを抽出
sed -E 's/.*"message":"([^"]+)".*/\1/' json.log

コード変換系

# Pythonのprint文をprint関数に変換(Python2→3)
sed -E "s/print ('.*')/print(\1)/g" *.py

# シングルクォートをダブルクォートに変換
sed "s/'/\"/g" file.js

# コメントアウト(行頭に # を追加)
sed 's/^/#/' file.txt

# コメントを解除(行頭の # を削除)
sed 's/^#//' file.txt

# 行末にセミコロンを追加
sed 's/$/;/' file.txt

# 末尾の不要なカンマを削除
sed 's/,\([[:space:]]*\)$/\1/' file.json

# インポート文をアルファベット順に並べ替えの前準備(抽出)
sed -n '/^import/p;/^from/p' script.py

設定ファイル系

# コメントと空行を除いた有効行のみ表示
sed '/^#/d;/^$/d' /etc/nginx/nginx.conf

# セクション間の内容を表示([section] から次の [ まで)
sed -n '/^\[database\]/,/^\[/p' config.ini | sed '$d'

# INIファイルの値を変更
sed -i 's/^max_connections = .*/max_connections = 200/' mysql.conf

# 特定のキーを含む行の値を変更
sed -i "s/^\(timeout\s*=\s*\).*/\1300/" config.txt

# 設定ファイルに新しい行を追加(特定行の後ろ)
sed -i '/^Port 22/a AllowUsers deploy' /etc/ssh/sshd_config

CSV / TSV 処理系

# CSVをTSVに変換
sed 's/,/\t/g' data.csv

# TSVをCSVに変換
sed 's/\t/,/g' data.tsv

# ヘッダ行を削除(1行目を削除)
sed '1d' data.csv

# ヘッダ行だけ取得
sed -n '1p' data.csv

# 特定列の前後のクォートを除去
sed 's/"//g' data.csv

# 空フィールドの行を削除(カンマが連続している行)
sed '/,,/d' data.csv

HTML / XML 処理系

# HTMLタグを削除
sed 's/<[^>]*>//g' file.html

# 特定タグの内容を抽出
sed -n 's/.*<title>\(.*\)<\/title>.*/\1/p' page.html

# コメントを削除(HTMLコメント)
sed 's/<!--.*-->//g' file.html

# 属性値を変更
sed 's/class="old-class"/class="new-class"/g' file.html

# 自己閉じタグに変換
sed 's/<br>/<br \/>/g' file.html

パス・URL 処理系

# ファイルパスのディレクトリ部分を削除(basenameの代わり)
echo "/usr/local/bin/node" | sed 's|.*/||'

# 拡張子を削除
echo "file.txt" | sed 's/\.[^.]*$//'

# 拡張子を変更
ls *.txt | sed 's/\.txt$/.md/'

# URLからプロトコルを除去
echo "https://example.com/path" | sed 's|https\?://||'

# URLからドメインだけ抽出
echo "https://example.com/path/to/page" | sed -E 's|https?://([^/]+).*|\1|'

システム管理系

# /etc/hosts に行を追加
echo "192.168.1.100 myserver" | sudo sed -i '$a\\192.168.1.100 myserver' /etc/hosts

# sudoers の安全な編集(visudo の代わりに使う場合)
sed -n '/^%sudo/p' /etc/sudoers

# cronの特定ジョブを削除
sed -i '/backup.sh/d' /etc/crontab

# ネットワーク設定のIPを変更
sed -i 's/address 192\.168\.1\.10/address 192.168.1.20/' /etc/network/interfaces

# sshd_configのパスワード認証を無効化
sed -i 's/^PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config

find・xargs との連携

# ディレクトリ内の全ファイルを一括置換
find . -name "*.txt" -exec sed -i 's/old/new/g' {} +

# スペースを含むパスに対応
find . -name "*.py" -print0 | xargs -0 sed -i 's/old_func/new_func/g'

# 最近更新されたファイルだけ処理
find . -name "*.conf" -mtime -7 -exec sed -i 's/DEBUG/INFO/g' {} +

# 特定のパターンを含むファイルだけ書き換え(grep と組み合わせ)
grep -rl "old_api" --include="*.py" . | xargs sed -i 's/old_api/new_api/g'

パフォーマンス Tips

LANG=C で高速化

# マルチバイト文字処理を無効化(ASCII限定なら高速)
LANG=C sed 's/ERROR/WARNING/g' huge.log

早期終了

# 最初の10行だけ処理して終了
sed '10q' file.txt

# 条件にマッチしたら終了
sed '/FOUND/q' file.txt

-n と p の組み合わせ

# 全行出力してから grep するより高速
sed -n '/ERROR/p' huge.log

macOS(BSD sed)との違い

macOSのsedはBSD系で、LinuxのGNU sedと動作が異なる箇所があります。

主な違い

機能GNU sed(Linux)BSD sed(macOS)
-i の書き方sed -i 's/a/b/' filesed -i '' 's/a/b/' file(空文字列必須)
-E(拡張正規表現)-E または -r-E のみ
\+(BRE)❌(-E+ を使う)
\w \d❌(POSIX文字クラスを使う)
; によるコマンド区切り一部動作が違う場合あり
0 アドレス✅(0,/pattern/

最も注意が必要:-i の違い

# ❌ macOS では失敗(バックアップ拡張子の引数なし)
sed -i 's/foo/bar/' file.txt

# ✅ macOS では空文字列を渡す必要あり
sed -i '' 's/foo/bar/' file.txt

# ✅ バックアップ付きならどちらも同じ書き方でOK
sed -i.bak 's/foo/bar/' file.txt

macOS で GNU sed を使う

brew install gnu-sed
# gsed として使える
gsed -i 's/foo/bar/' file.txt

# grep と同様に PATH に追加することも可能
echo 'export PATH="/opt/homebrew/opt/gnu-sed/libexec/gnubin:$PATH"' >> ~/.zshrc

クロスプラットフォームで動くスクリプトを書く場合、-i ''-i の違いに注意が必要です。CI環境(Linuxが多い)と開発マシン(macOS)で動作が変わることがあります。


sed vs 他ツールの使い分け

ツール向いているケース
sed行単位の置換・削除・挿入。シンプルなテキスト変換
awk列(フィールド)単位の処理・集計・条件分岐が複雑な場合
tr1文字単位の変換・削除(sed yより高速・シンプル)
cut特定の列を切り出す(CSVやTSVの列抽出)
perl -pe複雑な正規表現・後読み先読み・多機能置換
python複雑なロジック・JSONなど構造化データの処理
# これは sed が得意
sed 's/ERROR/WARNING/g' file.txt

# これは awk が得意(2列目が100以上の行を出力)
awk '$2 > 100' data.txt

# 1文字変換なら tr の方がシンプル
tr 'a-z' 'A-Z' < file.txt  # sed y より簡潔

トラブルシューティング

「unterminated address regex」エラー

# ❌ 閉じスラッシュが足りない
sed '/ERROR/d file.txt

# ✅ 正しい書き方
sed '/ERROR/d' file.txt

置換されない

主な原因:

  • 大文字小文字の違い → I フラグを試す: sed 's/error/ERROR/I'
  • 特殊文字のエスケープ漏れ → . * [ \ ^ $\でエスケープ
  • -g フラグ未使用で最初の1件しか置換されない
# . を文字として扱うにはエスケープ
sed 's/192\.168\.1\.1/10.0.0.1/' file.txt

# -F がある grep と違い、sed に固定文字列モードはない
# 特殊文字はすべて手動でエスケープする

-i でファイルが壊れた

# バックアップから復元
cp file.txt.bak file.txt

# 次回からは -i.bak でバックアップを作る習慣を
sed -i.bak 's/foo/bar/g' file.txt

macOS で -i が動かない

# ❌ Linux では動くが macOS では動かない
sed -i 's/foo/bar/' file.txt

# ✅ macOS 対応(空文字列を渡す)
sed -i '' 's/foo/bar/' file.txt

# ✅ 両方で動くポータブルな書き方
sed -i.bak 's/foo/bar/' file.txt && rm file.txt.bak

パイプ後ろの sed が遅い・反応しない

# tail -f との連携時
tail -f application.log | sed 's/ERROR/🔴 ERROR/g'
# → GNU sed はデフォルトでラインバッファなので通常OK
# → 反応しない場合は stdbuf を使う
tail -f application.log | stdbuf -oL sed 's/ERROR/[ERROR]/g'

よくある質問(FAQ)

Q1. sed と awk どちらを使えばいい?

シンプルな置換・削除・行の追加/削除は sed、列(フィールド)処理や複雑な条件分岐は awk が向いています。「1行で書けるかどうか」を目安にすると良いでしょう。

# sed で書けるシンプルな例
sed 's/foo/bar/g' file.txt

# これは awk の方が読みやすい(2列目が "ERROR" の行だけ出力)
awk '$2 == "ERROR"' file.txt

Q2. 置換前に確認する方法は?

-i をつけずに実行して出力を確認してから、問題なければ -i を追加するのが基本です。

# まず確認
sed 's/old/new/g' file.txt

# 問題なければ書き換え
sed -i.bak 's/old/new/g' file.txt

Q3. 複数行にまたがる置換はどうする?

GNU sed の -z オプションでファイル全体をNULL区切りで処理する方法と、N コマンドで複数行を結合する方法があります。複雑な場合は perl -0pepython を使う方が読みやすいことが多いです。

# GNU sed -z(ファイル全体を1つのレコードとして処理)
sed -z 's/foo\nbar/baz/g' file.txt

# perl の方がシンプルなことも
perl -0pe 's/foo\nbar/baz/g' file.txt

Q4. sed でループは書けますか?

ラベルとブランチ命令でループを実現できますが、可読性が極めて低くなります。ループが必要な複雑な処理には awkpython を使うことを強く推奨します。

# sed でのループ(行末スペースを繰り返し削除する例)
sed ':loop;s/  / /g;t loop' file.txt  # 複数スペースを1つに圧縮

Q5. s コマンドの g フラグを忘れやすい

g フラグなしは各行の最初のマッチのみ置換します。全部置換したいときは必ず g をつけましょう。

# 最初の1件だけ置換(g なし)
echo "aa bb aa" | sed 's/aa/XX/'
# → XX bb aa

# 全件置換(g あり)
echo "aa bb aa" | sed 's/aa/XX/g'
# → XX bb XX

Q6. 特定の行数だけ処理して終了したい

# 10行目まで処理して終了(それ以降は読まない)
sed '10q' file.txt

# head の代わりに使える(-n と p の組み合わせ)
sed -n '1,10p' file.txt

Q7. 行番号を出力したい

# = コマンドで行番号を出力
sed '=' file.txt | sed 'N;s/\n/\t/'

# または grep -n のような形式で
sed -n '/PATTERN/{=;p}' file.txt

Q8. sed のスクリプトファイルの拡張子は?

慣習的に .sed が使われますが、必須ではありません。

# cleanup.sed という名前で管理
sed -f cleanup.sed data.txt

Q9. sed より新しい・便利なツールはありますか?

ツール特徴
sdRust製、直感的な構文の sed 代替
perl -pePCRE・強力な後方参照・複雑な置換
python -c複雑なロジック・Unicode対応
ripgrep + sd検索と置換を分担する現代的な組み合わせ
# sd の例(より直感的)
sd 'old' 'new' file.txt
sd -f x '(?i)error' 'ERROR' file.txt  # 大文字小文字を無視

Q10. 正規表現の特殊文字をエスケープするのが面倒

変数を使った置換でドットやアスタリスクが入る場合は、pythonperl の方が便利なことが多いです。

# 変数に特殊文字が含まれる場合(自動エスケープが必要)
OLD="192.168.1.1"
NEW="10.0.0.1"
# sed では手動エスケープが必要
ESCAPED_OLD=$(echo "$OLD" | sed 's/\./\\./g')
sed "s/$ESCAPED_OLD/$NEW/g" file.txt

# perl なら quotemeta で自動エスケープ
perl -pe "s/\Q$OLD\E/$NEW/g" file.txt

参考リンク・関連資料

公式ドキュメント

代替ツール

関連記事(本サイト)


まとめ

sedコマンドはLinuxで最もよく使われるテキスト変換ツール。要点を再整理します。

  • 基本構文: sed [オプション] 'コマンド' [ファイル...]
  • 超頻出コマンド: s(置換)、d(削除)、p(出力)、a/i/c(追加・挿入・置き換え)
  • アドレス指定: 行番号(5, 1,10, $)、正規表現(/pattern/)、範囲(/start/,/end/
  • ファイル直接書き換え: -i(Linux)、-i ''(macOS)、バックアップは -i.bak
  • 正規表現の使い分け: デフォルト(BRE)・-E(ERE)
  • 複数コマンド: -e 複数指定、; 区切り、-f スクリプトファイル
  • パフォーマンス: LANG=C、早期終了(q
  • macOS注意: -i に空文字列が必要、-P 非対応
  • 代替ツール: awk(列処理)、perl -pe(高度な正規表現)、sd(直感的構文)

grepで検索しsedで変換する組み合わせは、ログ調査・設定ファイル管理・コード一括修正など、エンジニアのあらゆる作業で活用できます。本記事をブックマークして、ぜひ日常の作業効率化に役立ててください。


本記事は2026年6月時点の情報をもとに、GNU sed 4.x(Ubuntu 24.04標準)、BSD sed(macOS Sonoma/Sequoia)での動作確認に基づき作成しています。バージョンによってオプション挙動が異なる場合があるため、最新の情報は公式マニュアルもあわせてご確認ください。