Panda Noir

JavaScript の限界を究めるブログでした。最近はいろんな分野を幅広めに書いてます。

俺のためだけのsedまとめ

迷ったときにとりあえずこれ読めば8割くらいわかるように書きました。

sedでできること

sedは受け取った文字列を加工するためのコマンドです。パイプラインやファイルから文字列を受け取って処理します。置換や削除などができます。四則演算はできません。

sedの使い方

sedコマンドにsedスクリプトを渡す方法は2通りあります。

  • 直接スクリプトを書く(sed -e 'sed-script')
  • sedスクリプトを書いたファイルを指定する(sed -f sed-file)

sedスクリプト

sedの基本動作は「条件を満たす行に対してコマンドを実行する」というものです。例えば「10行目を削除する」「3、6、9が含まれている行を削除する」といったことが可能です。

処理の全体の流れは次のようになります。

  1. 入力から1行読み込み、パターンスペースに格納する
  2. パターンスペース内の文字列にコマンドを実行する
  3. パターンスペースの内容を出力する(-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が含まれる行を削除する

参考