sedの後方参照を使った置換を理解する
シス管系女子2の第7話に出てくる sed
コマンドの「後方参照」がいまいち理解できなかったので調べてみました。
sedコマンドとは
「Stream EDitor」の略で、「sed スクリプトコマンド ファイル名」で、指定したファイルをコマンドに従って処理し、標準出力へ出力します。ファイル名を省略した場合は、標準入力からのデータを処理します。sedコマンドでは、パイプとリダイレクトを活用するのが一般的です。
【 sed 】コマンド(基礎編)――テキストファイルを編集する:Linux基本コマンドTips(53) - @IT
vim
などのような対話型エディタではなく、コマンドラインのオプションのみで指示。
流れてくるテキストを編集するから「ストリーム(流れの)エディタ」と言います。
主に文字列の置換、抽出、削除などの処理に使われるコマンド。
ちなみにsed
コマンドは編集結果を標準出力に出力するので元のファイルは変更しないので、パイプやリダイレクトを組み合わせて使われることが多いです。
置換
後方参照の前にsed
コマンドでよく使われる通常の置換処理についてまとめておきます。(細かい話は省略して簡単にまとめます。)
例) sed_test.txtの内容
ABC ABCABC ABCABCABC
- 行頭に出てくる文字列だけ置換
sed "s/置換前/置換後/" ファイル名
$ sed "s/ABC/DEF/" sed_test.txt DEF DEFABC DEFABCABC
- すべての文字列を置換する場合は末尾に
g
を付ける
sed "s/置換前/置換後/g" ファイル名
$ sed "s/ABC/DEF/g" sed_test.txt DEF DEFDEF DEFDEFDEF
ちなみにcat
コマンドと |
パイプラインでつなげてsed
コマンドを使っても同じです。
$ cat sed_test.txt | sed "s/ABC/DEF/g"
後方参照
本題で、これは置換前の内容を置換後に引用させるためのものです。 例えばABCの部分を後ろにDEFを付けてABCDEFとしたい場合などに使えます。 具体的にどうするかというと、
- 引用したい部分を
(
)
で囲む。(拡張正規表現の-r
オプションを付ける)-r
オプションを付けない場合は\(
と\)
で囲んでエスケープすればいいが可読性が少し悪くなる。
- そうすると、
(
)
で囲った部分を順に\1
\2
で参照することができる。(
)
が1つなら\1
のみ、2つなら\1
\2
、3つなら\1
\2
\3
...で参照可。
$ sed -r "s/(ABC)/\1DEF/g" sed_test.txt ABCDEF ABCDEFABCDEF ABCDEFABCDEFABCDEF
2箇所参照の場合
$ sed -r "s/(A)(B)/\1D\2E/g" sed_test.txt ADBEC ADBECADBEC ADBECADBECADBEC
上記はAが\1
、Bが\2
で参照できるようになって、ABC→ADBECと置換されている。
後方参照の理解は少し難易度が高いですが、( )で囲った部分を引用という事がわかれば理解しやすそうです。