sed(stream editor)は、テキストを行単位で処理し、置換・削除・抽出などの編集を自動化するコマンドです。
ファイルを直接編集するのではなく、標準入力や指定ファイルを読み込んで変換した結果を標準出力に出力します。ログ加工・設定ファイルの一括変換・パイプラインでのテキスト整形など、実務のシェルスクリプトで幅広く使われます。
構文(Syntax)
sed [オプション] 'スクリプト' [ファイル...]
sed [オプション] -e 'スクリプト1' -e 'スクリプト2' [ファイル...]
sed [オプション] -f スクリプトファイル [ファイル...]
主なオプション一覧
| オプション | 説明 | 使用例 |
|---|---|---|
-n | 自動出力を抑制(p コマンドと組み合わせて使う) | sed -n '2,5p' file.txt |
-i | ファイルを直接書き換え(in-place 編集) | sed -i 's/old/new/g' file.txt |
-i.bak | バックアップを作成してから in-place 編集 | sed -i.bak 's/foo/bar/g' file.txt |
-e | 複数のスクリプトを指定 | sed -e 's/a/A/' -e 's/b/B/' file.txt |
-f | スクリプトをファイルから読み込む | sed -f script.sed file.txt |
-E / -r | 拡張正規表現(ERE)を使用 | sed -E 's/(foo|bar)/baz/g' file.txt |
主なコマンド(スクリプト内)
| コマンド | 説明 | 例 |
|---|---|---|
s/pattern/replacement/ | 最初にマッチした箇所を置換 | s/error/ERROR/ |
s/pattern/replacement/g | 行内の全マッチを置換 | s/foo/bar/g |
d | 行を削除 | /^#/d(コメント行を削除) |
p | 行を出力(-n と組み合わせて抽出) | -n '/ERROR/p' |
q | 指定行で処理を終了 | 5q(5行目まで出力) |
atext | マッチ行の次に行を追加 | /^HOST/aPORT=8080 |
itext | マッチ行の前に行を挿入 | /^SERVER/i# server config |
ctext | マッチ行を置き換え | /^USER=/cUSER=admin |
y/src/dst/ | 文字を1対1で変換(tr に相当) | y/abc/ABC/ |
実行例
文字列を置換する(基本)
echo "Hello World" | sed 's/World/Bash/'
出力例:
Hello Bash
行内のすべてのマッチを置換する(g フラグ)
echo "aaa bbb aaa" | sed 's/aaa/XXX/g'
出力例:
XXX bbb XXX
ファイルを直接書き換える(-i)
sed -i 's/localhost/192.168.1.1/g' config.conf
バックアップを残しながら編集する場合:
sed -i.bak 's/localhost/192.168.1.1/g' config.conf
# config.conf.bak が元ファイルとして保存される
特定の行を抽出する(-n と p)
# 3行目から7行目を抽出
sed -n '3,7p' access.log
# ERROR を含む行だけを抽出(grep と同等)
sed -n '/ERROR/p' app.log
コメント行・空行を削除する
# # で始まる行を削除
sed '/^#/d' config.txt
# 空行を削除
sed '/^$/d' config.txt
# コメント行と空行を同時に削除
sed -e '/^#/d' -e '/^$/d' config.txt
複数ファイルを一括置換する
# カレントディレクトリの全 .conf ファイルを一括置換
sed -i 's/v1.0/v2.0/g' *.conf
# find と組み合わせて再帰的に置換
find . -name "*.txt" | xargs sed -i 's/old_value/new_value/g'
拡張正規表現で置換する(-E)
-E(-r)を付けると () や {}、| がそのまま特殊文字として使える拡張正規表現(ERE)になる。正規表現の書き方の基礎はパターン・正規表現の使い分けも参照。
# 複数パターンをまとめて置換
sed -E 's/(foo|bar)/baz/g' file.txt
# 日付形式を変換(YYYY-MM-DD → DD/MM/YYYY)
echo "2024-06-15" | sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3\/\2\/\1/'
出力例:
15/06/2024
行番号を指定して操作する
# 1行目を削除(ヘッダー行の除去など)
sed '1d' data.csv
# 2行目だけ置換
sed '2s/old/new/' file.txt
# 最終行を削除
sed '$d' file.txt
行を追加・挿入する
# HOST= の行の次に PORT=8080 を追加
sed '/^HOST=/a PORT=8080' config.txt
# SERVER= の行の前にコメントを挿入
sed '/^SERVER=/i # Server configuration' config.txt
grep・xargs と組み合わせたパイプ処理
# grep で絞り込んでから sed で置換
grep "^ERROR" app.log | sed 's/ERROR/[ERR]/'
# find で対象ファイルを絞り込み、xargs で sed を一括実行
find /etc -name "*.conf" | xargs sed -n '/^#/p'
→ grep コマンドの使い方 や xargs コマンドの使い方 も参照してください。
関連コマンド
grep: パターンにマッチする行を検索・抽出する。sedと組み合わせて絞り込み→加工のパイプラインが作れる- find : ファイルを検索して
sedの処理対象として渡すときに使う(find . -name "*.conf" | xargs sed ...) xargs:findやgrepの出力をsedの引数として渡すことで、複数ファイルの一括処理が可能になるawk: フィールド単位の処理や計算が必要な場合はawkが向いている。sedは行単位の置換・削除、awkは列単位の処理と使い分ける
備考
-iオプションの挙動は OS によって異なる。macOS ではsed -i ''(空文字引数が必須)、Linux ではsed -iのみで動作する。- 置換パターンの区切り文字は
/以外でも使える。ファイルパスを含む場合はs|/old/path|/new/path|gのように|を使うとエスケープが不要になる。 - 大量のファイルを処理する場合、
sed -iを直接使うよりfind | xargs sed -iを利用するほうがパフォーマンスが良いことが多い。 - GNU sed(Linux)と BSD sed(macOS)は微妙な互換性の差があるため、クロスプラットフォームで使うスクリプトでは注意が必要。
参考
- manページ: man7.org sed(1)
- GNU sed マニュアル: https://www.gnu.org/software/sed/manual/sed.html

コメント