それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

sed で行挿入をシンプルに行う。

sedなら出来る。

sed で検索文字列の直前に行を作って入れられる。 今回使ったsedgnu 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コマンドはポケモン的進化をたどっています。

  • ed は進化して exになりました。
  • exがスクリーン機能でvi になり、viは進化してvim になりました。
  • vim は さらに nvim になりした。

その一方で

  • ed は進化して sedになりました。
  • sedは進化して gnu sedになりました。

その間に、難しくなりすぎた 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 といえば、ia,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

vimia の違いは知ってますよね。

ここまでわかると、i (insert)のかわりにa (append)を使ってみる。

aはAppendだから続く行に追加出来ると予想できますよね。

echo hello | sed '/hello/a world'

これは、 hello をさがして Apppend "world" と解釈できる。

コマンド例

echo hello | sed '/hello/a world'

実行結果

hello
world

ね。Vimと同じでしょ。

sedgrep も同じ祖先

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を使って設定書き換えるのも楽ちんになります。