togatttiのエンジニアメモ

過度な期待はしないでください.

sedで、範囲指定してから、文字列置換を使う

sedで、範囲指定してから、文字列置換する方法を備忘録として残しておく。

例えば、以下のようなファイルがあるとする。

$ cat sample_http.conf
<VirtualHost example.com:80>
  User www
  Group www
  Port 80
  SSLDisable
  ServerAdmin admin@example.com
  ServerName example.com
</VirtualHost>

<VirtualHost example.com:443>
  User www
  Group www
  Port 443
  SSLEnable
  ServerAdmin admin@example.com
  ServerName example.com
</VirtualHost>

そして、ServerAdminをそれぞれ、

に変更したい。

これをsedで、行うためには、こうする。

$ sed -i.bak -e '/<VirtualHost .*:80>/,/<\/VirtualHost>$/s|admin|http-admin|' sample_httpd.conf
$ sed -i.bak -e '/<VirtualHost .*:443>/,/<\/VirtualHost>$/s|admin|http-admin|' sample_httpd.conf

実行すると思い通りの挙動になる。

<VirtualHost example.com:80>
  User www
  Group www
  Port 80
  SSLDisable
  ServerAdmin http-admin@example.com
  ServerName example.com
</VirtualHost>

<VirtualHost example.com:443>
  User www
  Group www
  Port 443
  SSLEnable
  ServerAdmin https-admin@example.com
  ServerName example.com
</VirtualHost>

公式風に書くと、

sed -e '/範囲指定開始文字列/,/範囲指定終了文字列/s|置換前文字列|置換後文字列|' ファイル

実際に実行したコマンドを簡単に見てみると、

$ sed -i.bak -e '/<VirtualHost .*:80>/,/<\/VirtualHost>$/s|admin|http-admin|' sample_httpd.conf

について、/<VirtualHost .*:80>/,/<\/VirtualHost>$/ で、

作業の範囲が、80番のVirtualHostディレクティブ内の内容であることを明示している。

続けて、置換の構文を s|admin|http-admin| 指定している。