テキストの編集は大抵vimでやっちゃうので滅多に使わないのですが、稀にコマンドラインでファイルの置換を完結させたり、一つのテンプレートファイルから中身を一部置換したファイルを複数生成する必要が発生し、それをコマンドラインで済ませたいことがあります。
そんなときに、sed (Stream Editor) コマンドを使うのですが、その度に使い方を調べているのでここメモしておきます。
基本的な使い方は、
sed -e {編集コマンド} {入力ファイル}
です。パイプラインで利用する場合は{入力ファイル}を省略できます。
ファイル中の aaa を xxx に置換する場合は次のように書きます。
$ cat input.txt
aaa,bbb,ccc
ddd,eee,fff
$ sed -e s/aaa/xxx/g input.txt
xxx,bbb,ccc
ddd,eee,fff
-e は省略可能で、省略した場合は最初の引数が編集コマンドとみなされます。
なので、大抵の場合は -e を省略して大丈夫です。
$ cat input.txt | sed s/aaa/xxx/g
xxx,bbb,ccc
ddd,eee,fff
-e オプションは複数指定することもできて、同時に複数の置換をかけることもできます。
$ sed -e s/aaa/xxx/g -e s/bbb/yyy/g input.txt
xxx,yyy,ccc
ddd,eee,fff
編集コマンドは、シングルクオーテーション、もしくはダブルクオーテーションで囲むこともできます。(置換前後の文字列のどちらかにスペースを含む場合は、確実に囲むようしましょう。そうしないとエラーになります。)
$ sed "s/aaa/X Y G/g" input.txt
X Y G,bbb,ccc
ddd,eee,fff
置換結果を別のファイルに出力する時は、他のシェルコマンド同様にリダイレクションしてあげれば大丈夫です。僕はもっぱらその形で使います。
例えば、 input.txt の aaa を xxx に置換した output.txt を生成するには次のようにします。
$ sed "s/aaa/xxx/g" input.txt > output.txt
元のファイルをそのまま書き換えることもでき、その場合は
-i {拡張子} オプションをつけます。
すると、{元のファイル名}{拡張子} というファイル名でバックアップを取った上で、入力ファイルを書き換えてくれます。
バックアップはいらないよという場合は、拡張子として長さ0の文字列を渡します。
$ sed -i '' -e 's/aaa/xxx/g' input.txt
この時、” をつけ忘れると、 input.txt-e という変な名前のファイルが残ってしまうので注意してください。
多くの編集コマンドを同時に実行したい場合などは、編集コマンドをまとめたファイルを用意しておき、それを -f オプションで渡すこともできます。
$ cat edit.sed
s/aaa/xxx/g
s/bbb/y y y/g
s/ccc/zzz/g
$ sed -f edit.sed input.txt
xxx,y y y,zzz
ddd,eee,fff
あとは、入力ファイルはスペース区切りで複数同時に渡すことも可能です。
-i オプションをつけている場合は、渡した入力ファイルたちがそれぞれ編集されます。
-i オプションがない場合は、それぞれのファイルを編集した結果が連結されて標準出力に返されます。
sed コマンドで文字列を置換することに関して主に知っておくべきことはこれくらいかなと思います。