【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/aaa\nccc/#aaa\nabc\nccc/;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
これをシェルスクリプトに組み込んでやれば、人間が介在する手間を最小限に、設定ファイルの編集ができそうです。
今まで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箇所だけ置換したい・・・って場合は、、、
「sed 改行 置換」でググったら2chのスレにそのものズバリな答えが出てきたのでできました。
例えば、「aaa<改行>bbb」は置換せずに、「aaa<改行>ccc」は「#aaa<改行>abc<改行>ccc」にしたいという場合、
sh-3.00$ sed -n '${p;q};:s; N;s/aaa\nccc/#aaa\nabc\nccc/;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
これをシェルスクリプトに組み込んでやれば、人間が介在する手間を最小限に、設定ファイルの編集ができそうです。
トラックバック(0)
このブログ記事を参照しているブログ一覧: 【sed】【小ネタ】ある行に文字列を挿入しつつ置換する
このブログ記事に対するトラックバックURL: http://www.blogcube.info/cgi-bin/mt-tb.cgi/80

いいアイディアだ。
いったん sed のコマンドを作ってしまえば、それをいくつものサーバの設定ファイルに対して機械的に適用していけば作業が完了する。っていう寸法ですね。
ただ、最初にコマンドを作る際に間違ったコマンドを作ってしまうと、全部のサーバに間違った変更を与えてしまいますね(あたりまえww)。なので、sed のコマンド作成時には、しっかり確認が必要だね。diff コマンドで、意図しない変更が行われていないかを確認したり。
あと、作った sed コマンドを連続で適用していくときに、それぞれの元ファイルが、想定した内容のものであるのかを確認できるといいんだけどね。