迷ったときにとりあえずこれ読めば8割くらいわかるように書きました。
sedでできること
sedは受け取った文字列を加工するためのコマンドです。パイプラインやファイルから文字列を受け取って処理します。置換や削除などができます。四則演算はできません。
sedの使い方
sedコマンドにsedスクリプトを渡す方法は2通りあります。
- 直接スクリプトを書く(
sed -e 'sed-script'
) - sedスクリプトを書いたファイルを指定する(
sed -f sed-file
)
sedスクリプト
sedの基本動作は「条件を満たす行に対してコマンドを実行する」というものです。例えば「10行目を削除する」「3、6、9が含まれている行を削除する」といったことが可能です。
処理の全体の流れは次のようになります。
- 入力から1行読み込み、パターンスペースに格納する
- パターンスペース内の文字列にコマンドを実行する
- パターンスペースの内容を出力する(
-n
コマンドをつけていた場合は出力しない)
パターンスペースとはバッファのことです。
この流れを理解できていれば、次のコマンド意味がわかるはずです。
$ seq 1 5 | sed -e "2 a append 3 a append 4 a append"
アドレス
コマンドを実行したい行を、アドレスを用いて指定します。アドレスを指定せずにコマンドを実行すると、すべての行に対して実行されます。
アドレスは主に正規表現か、行番号で指定します。正規表現を指定した場合はパターンにマッチする行に対してコマンドが実行されます。他にも以下のような指定方法があります。
- 正規表現
- 行指定
- 範囲指定(1,10など)
- ステップつき範囲指定(3\~2なら、3行目以降を2行おきに指定する)
コマンド
sedで使用できるコマンドは以下のようなものがあります。
y/置換前/置換後/
後述s/ターゲット文字列/リプレース文字列/
ターゲット文字列をリプレース文字列で置き換えます。s/hoge/fuga/g
というように、gフラグをつけることで一致するすべての箇所を置換できます。d
行を削除します。c テキスト
テキストで行全体を置換をします。a テキスト
指定位置の1行うしろにテキストを追加します(例:3 a append
を実行すると3行目にappendという行が追加される)i テキスト
指定位置にテキストを追加します(例:3 i insert
を実行すると3行目にinsertという行が追加される)
yコマンドはすこし説明が難しいので、例を交えながら説明します。
たとえば、Aをaに、Bをbに変えたいとします。そのとき、sedではsed -e 's/A/a/g' | sed -e 's/B/b/g'
とする代わりにyコマンドを用いてsed -e 'y/AB/ab/'
と書くことができます。
このように、ある文字と別の文字の対応づけをする(つまり換字を行う)コマンドがyコマンドになります。
アドレス例
$ seq 1 5 | sed -e " 3 d" #3行目を削除 1 2 4 5 $ seq 1 5 | sed -e "1~2 d" #1行目以降を、2行おきに削除 1 3 5 $ seq 1 5 | sed -e "2,4 d" #2行目から4行目を削除 1 5 $ seq 1 5 | sed -e "/[369]/ d" #3,6,9が含まれる行を削除 1 2 4 5
コマンド例
$ seq 1 5 | sed -e " 3 y/12345/abcde/" #1をa、2をb…とういふうに変換 a b c d e $ seq 1 5 | sed -e " 3 y/15/51/" #1と5を入れ替える 5 2 3 4 1 $ seq 1 5 | sed -e "3 i insert" #3行目の位置にinsertと挿入 1 2 insert 3 4 5 $ seq 1 5 | sed -e "3 a append" #3行目の後ろにappendと追加 1 2 3 append 4 5 $ seq 1 5 | sed -e " 3 c hoge" 3行目をhogeで置き換える 1 2 hoge 4 5
ここまでは見やすさのためにアドレスとコマンドの間にスペースを入れていましたが、sed -e "3choge"
のようにスペースを抜いてもきちんと動作します。
実はVimの置換はSedだった
実はVimの:s/target/replacement/
というコマンドはSedと同じように書くことができます(相違点も多いのでVim版Sedくらいに捉えておくと扱いやすいです)。
:1,9/hoge/fuga/
1行目から9行目のhogeをfugaに置換する:/1st/s/hoge/fuga/
1stが含まれる行を探して、hogeをfugaに置換する。ただし、複数の行に対して置換を行わない模様。:/OMG/d
OMGが含まれる行を削除する