sedなら出来る。
sed で検索文字列の直前に行を作って入れられる。 今回使ったsedはgnu sedです。
マッチの直前に行を追加
サンプル
echo hello | sed '/hello/i world'
hello
の直前にsay
を入れました。
sed で行挿入をシンプルにやる。
sed を使って、設定ファイルを書き換えるコマンドを作っていると。
マッチ箇所の「直前」に行を入れたい。ということがよくある。
たとえば、次のようにコメントアウトをしつつ、設定を書きたい。など
leftauth=secret #leftauth=pubkey
行挿入の例
これらは、sedで動く行挿入の例デス。
sed '1i FoooBar' sed '1a FoooBar' sed '/Fooo/a Baaar' sed '/Fooo/i Baaar'
複数行を挿入する例
'\n'
を使えばいい
echo names| sed -e '/names/a = ["nao"\n"aki",\n"rin"\n]'
複数行をコピペで入れるには、バックスラッシュでエスケープする
バックスラッシュの例
echo names| sed -e '/names/a = ["nao"\ "aki",\ "rin"\ ]'
-e
を使わずに置換するときは両方使う。
sed -i "/table->id();/a \\ \$table->string( 'title' );\n\ \$table->string( 'ISBN' );\n\ \$table->string( 'author' );\n\ \$table->string( 'located' );\ " database/migrations/*create_book*table.php
コメントアウト
ただし、コメントアウトをする場合は、挿入ではなく。置換になる。
cat /etc/rsyslog.conf | sed -e '/load="imklog"/s/^/#/'
上記のように、マッチした箇所を「置換する」
ちょっとむずいかもしれないが、vim / vi / ed と同じように。「指定範囲✖操作」となっている。
sed の '/i/' を知るための進化の系譜。
此処から先は、 i
ってなんだ?と思った人向けです。
sedは stream editor と言われます。わたしは、special な edコマンド
だと思っています。
ed
コマンドとは、editorコマンドのことです。
edが進化した vi / sed
ものすごく、「ざっくり」いうと、edコマンドはポケモン的進化をたどっています。
その一方で
その間に、難しくなりすぎた vi を敬遠する人がいて
- nano は vi / ed /ex コマンドがわからない人向けに作られました。
vim のEXコマンド(edモード)とsed
vim のEXコマンドモード(edコマンドモード)と同じ、というかedから派生した(とわたしは信じています。)
sedもedの進化系と考えれば、vim で覚えたEXコマンドのノウハウもsedで使えたりするのです。
「範囲✖命令」がvim の特徴
vimを思い出しましょう。
vim のed コマンドモードでは、「範囲xコマンド」
になってる
:%s/hello/world/ :1,3/hello/world/ :'<,'>s/hello/world/
これは、 次のように解釈する。
EXコマンド | 範囲 | 操作 | 操作内容 |
---|---|---|---|
%s/hello/world/ | % | s | /hello/world/ |
1,3/hello/world/ | 1-3 | s | /hello/world/ |
<,>/hello/world/ | 1-3 | s | /hello/world/ |
%
は、「全部の行」、1,3
は「1-3行目」を意味する。<,>
は選択範囲
s
は置換 、/hello/world/
は「置換前・置換後」である。
s
(置換) の他になにかあるのか?
s/i/a/d のコマンド
vim といえば、i
やa
,d
を押したことがあるはずだ。あれらが「操作」である。
削除d
の例
削除は、次のように行指定で出来る
1,3d 222d
sed で d,i,s,a
sed は この ed エディタの系譜になるので、vim のEx(Ed)モードと大体似ている。sed の s はストリームのSで1行ごと処理をする。
冒頭の例を分解する。
hello という文字列の直前に挿入
echo hello | sed '/hello/i say'
この例は、次のように解釈できる。/hello/
を探して Insert
"say"
sed で 後続行に追加 : /hello/a
vim で i
と a
の違いは知ってますよね。
ここまでわかると、i
(insert)のかわりにa
(append)を使ってみる。
a
はAppendだから続く行に追加出来ると予想できますよね。
echo hello | sed '/hello/a world'
これは、 hello
をさがして Apppend
"world"
と解釈できる。
コマンド例
echo hello | sed '/hello/a world'
実行結果
hello world
ね。Vimと同じでしょ。
sed も grep も同じ祖先
grep の名の由来は、ラインエディタedのコマンド g/re/p である。その意味するところは「global regular expression print(ファイル全体から/正規表現に一致する行を/表示する)」で略号になっている[1]。
姉妹コマンドとして、正規表現ではなくリテラル(即値文字列)のみを扱う高速な fgrep[2]、拡張正規表現が使える egrep[3] がある。POSIX では fgrep、egrep を旧形式としていて、それぞれ grep -F、grep -E を使うことを標準としている。Linux Standard Baseでも指定コマンドになっている[4]。 wikipedia|grep
へぇ grep って ed 由来の名称なんですね。
つまり、こういうことか!
sed 'g/re/p'
そういえば、fgrep は思考停止出来ていいですよね。
以上が私の理解。
私の理解は、「進化」をたどって理解するという、回りくどいやり方で理解してますが、単純に例だけを覚えてもいいと思う。
sedをつかってマッチした行を削除とか、追加とか
vimは必須知識
vim は難しいとか、 vi は要らないとかいわずに、nanoを使わずにed/vi/vim(ex)/sedを使ってみましょうよ。
きっといいことがありますよ。
sedを使って設定書き換えるのも楽ちんになります。