sed実践レシピ
ここまでで置換とアドレス指定という sed の基本部品はそろいました。ここからは、それらを現場でどう組み合わせるかという「実践レシピ」を見ていきます。範囲を指定して間だけを抜き出す、複数の処理を一度に流す、-i で書き換える前にバックアップを残す、といった実務でそのまま使える型を身につけましょう。あわせて、sed が苦手とする場面と awk に切り替える判断基準も押さえます。
sed の置換とアドレス指定の書き方はもう覚えた。だが実務で本当に困るのは、単発の1行を直すときではなく、決まった作業を毎回同じ手順でこなしたいときだ。
ログから特定区間だけ抜き出す、設定ファイルの数か所を一気に直す、失敗したら困るのでバックアップも残す。こうした「よくある場面」に対して、決まった書き方の型を持っておくと、その場で毎回組み立て直す手間がなくなる。
この節では、そのレシピカードを何枚か作っていく。まずは範囲を指定するアドレスの応用から始めよう。
🎯 「ここからここまで」を指定する
行番号1つや正規表現1つで狙う行を指定する方法はすでに見た。sed では、それをカンマでつなぐと「範囲」を表せる。
1,5d と書けば1行目から5行目までを削除し、/BEGIN/,/END/d と書けば BEGIN を含む行から END を含む行までをまとめて削除する。
行番号と正規表現は混ぜて使うこともでき、10,/^$/d は「10行目から、最初に現れる空行まで」を削除する、という指定になる。
削除の d と表示の p はどちらも1文字のコマンドで、その前に置いたアドレスが「どの行に効かせるか」を決める、という関係になっている。
範囲アドレスがとくに役立つのは、ログの中の「ある処理の開始から終了まで」のように、境目が行番号ではなく文字列で決まる場面だ。/START処理/,/END処理/p と書けば、ファイルが日によって長さの違うログでも、境目の文字列さえ変わらなければ同じコマンドで狙った区間を抜き出せる。
この意味で範囲アドレスは、行番号による固定的な指定と、内容に応じて動く柔軟な指定の両方を状況に応じて選べる点が強みになる。
👀 抜き出したいときは -n と p のコンビ
sed は何も指定しないと全行を自動で出力する。範囲アドレスと組み合わせて特定区間だけを見せたいときは、自動出力を止める -n と、表示コマンドの p をセットで使う。
sed -n '2,4p' access.log なら2〜4行目だけが表示され、これは head と tail を組み合わせて狙った区間を抜き出すのと同じ感覚で使える。
-n を付け忘れると、対象行が自動出力の分とpの分で二重に出てしまう失敗はもう経験済みのはずだ。抜き出し用途では「-n と p は必ずペア」と体で覚えておくとよい。
grep と同じ結果になるなら grep を使えばよいと思うかもしれないが、sed ならではの利点もある。範囲アドレスでの抜き出しに続けて、同じコマンドの中でそのまま置換や削除も加えられるため、検索と加工を一連の流れとして1つのスクリプトにまとめられる。
🔗 1つのコマンドで済ませたい、複数の処理をつなぐには
実務でよくあるのは、削除と置換など、複数の処理を1回のコマンド実行でまとめて済ませたい場面だ。sed にはそのための書き方が2つある。
1つ目は -e オプションを複数回並べる方法で、sed -e '1d' -e 's/foo/bar/' file のように書く。それぞれの -e が1つの処理を表し、上から順に適用される。
2つ目はセミコロン ; で処理をつなぐ方法で、sed '1d; s/foo/bar/' file と1つの引用符の中にまとめて書ける。
どちらも結果は同じで、-e は処理ごとに区切りがはっきりして見やすく、; は短く1行にまとめたいときに向く、という好みの違いだと考えてよい。
処理の順番は結果に影響することがある。先に削除してから置換するのと、先に置換してから削除するのとでは、対象になる行が変わる場合があるので、意図した順に並べる意識は持っておきたい。
処理を3つ以上つなげたいときも考え方は同じで、-e を必要な数だけ増やすか、; で区切って並べていけばよい。詰め込みすぎると読みにくくなるので、処理が多いときは -e を縦に並べる書き方を選ぶのも実務的な工夫だ。
💾 本番ファイルを書き換える前に、必ずやること
-i を付ければファイルを直接書き換えられることはすでに学んだ。実務ではここに、もうひと手間加えるのが定石だ。
-i の直後に .bak のような拡張子を書き足す -i.bak という形にすると、書き換え前の内容が同じディレクトリに file.bak として自動で残る。
バックアップの拡張子は .bak に限らず .orig でも日付入りでも構わない。大切なのは「書き換える前の状態を、必ずどこかに残す」という習慣そのものだ。
慣れてきても、初めて使うパターンや複数ファイルへの一括適用では、まず -i なしで結果を画面で確認し、問題なければ -i.bak を付けて実行する、という2段階の手順を踏むと安心できる。
複数のファイルをまとめて書き換えたいときは sed -i.bak 's/old/new/g' *.conf のようにワイルドカードを使えるが、対象が一気に増えるぶん事前確認とバックアップの重要性はいっそう増す。
🧱 sed にも苦手な場面がある
ここまで見てきたとおり sed は行単位の処理に強い。だが、その裏返しとして、行をまたぐ処理はそもそも仕組み上苦手だ。
sed は基本的に1行ずつ読み込んで処理するため、「ある行の内容を見て、次の行を書き換える」といった複数行にまたがる加工は、通常の使い方の範囲では複雑になりすぎる。
たとえば「前後の行を見比べて重複を消す」「複数行にまたがる1つのブロックを丸ごと書き換える」といった処理は、awk のほうが変数を使って前の行の情報を覚えておけるぶん、ずっと素直に書ける。
つまり「行の中の置換・削除、決まった範囲の抜き出し」は sed の土俵、「行をまたいだ集計・複数条件の組み合わせ」は awk の土俵、というすみ分けだ。
見分け方の目安はシンプルで、「今扱う情報が1行の中だけで完結しているか」を自分に問うとよい。完結しているなら sed で十分だし、他の行と比べたり合計を出したりする必要が出てきたら、それは awk へ切り替えるサインだ。
この使い分けの感覚さえ持っておけば、無理に1つの道具で全部済ませようとせず、場面に応じて最短距離のコマンドを選べるようになる。sed の実践レシピは、その最初の判断基準にもなってくれる。