【sed】【小ネタ】ある行に文字列を挿入しつつ置換する


いつもいつも、configファイルを編集するのに、私の場合はviで既存の行をコピーしてコメントアウトし、その真下に変更後の内容を書きます。こうすることで、変更履歴がわかりやすくなるのと、万が一元に戻す必要がある場合に楽だからです。

今までviでyypしてたりしてたのですが、シェルスクリプトなどで行う際に、なるべく対話式じゃないやり方でできないかなーと思ったのです。そこで思いついたのが、sedを使う方法。

まず、hogeというファイルのaaaという行をコメントアウトして、aaaとbbbの間にabcを挿入するという例でやってみます。

sh-3.00$ cat hoge
aaa
bbb
ccc
ddd
eee

それでは、いざ置換!

sh-3.00$ sed s/aaa/#aaa'n'abc/g hoge
#aaa
abc
bbb
ccc
ddd
eee

こうすることで、aaaの行がコメントアウトされ、aaaとbbbの行の間にabcが挿入されました。
けど、aaaという行が複数あって、どこか1箇所だけ置換したい・・・って場合は、、、
誰か教えてくださいorz
「sed 改行 置換」でググったら2chのスレにそのものズバリな答えが出てきたのでできました。

例えば、「aaa<改行>bbb」は置換せずに、「aaa<改行>ccc」は「#aaa<改行>abc<改行>ccc」にしたいという場合、

sh-3.00$ sed -n '${p;q};:s; N;s/aaanccc/#aaanabcnccc/;P;D;b s' hoge
aaa
bbb
#aaa
abc
ccc
ddd
eee

これでできます!
これで、例えば新しくサーバ作ったときに、sshd_configでrootの直接sshログインを禁止したりするのに役立ちそうです。

# cd /etc/ssh
# cp -p sshd_config sshd_config.orig

【rootでのsshログインを禁止する】
# sed -i s/#PermitRootLogin yes/#PermitRootLogin yes'n'PermitRootLogin no/g sshd_config

【X11転送を禁止する】
# sed -i s/#X11Forwarding no/X11Forwarding no/g sshd_config
# sed -i s/X11Forwarding yes/#X11Forwarding yes/g sshd_config

【接続元の名前解決にDNSを使わない】
# sed -i s/#UseDNS yes/#UseDNS yes'n'UseDNS no/g sshd_config

これをシェルスクリプトに組み込んでやれば、人間が介在する手間を最小限に、設定ファイルの編集ができそうです。