sedで置き換える文字に&(アンパサンド)を使う場合はエスケープが必要

&を使うと意図通りでない文字列に置き換わる

例えばabcという文字列をa&cに置き換えたいと思って以下のコマンドを実行しても何も変わらない。

$ echo "abc" | sed "s/b/&/"
abc

他にもHTTPパラメータを見つけてその後ろに&でパラメータを追加したい、みたいなときに sed "s/foo=xxx/foo=xxx&bar=yyy/"のように書くとうまくいかない。

$ echo "foo=xxx" | sed "s/foo=xxx/foo=xxx&bar=yyy/"
foo=xxxfoo=xxxbar=yyy

期待値はfoo=xxx&bar=yyyだがfoo=xxxfoo=xxxbar=yyyとなる。

\(バックスラッシュ)でエスケープすると&で置き換わる

&を\(バックスラッシュ)でエスケープすると意図通り置き換わる。

$ echo "abc" | sed "s/b/\&/"
a&c

HTTPパラメータの例でも以下のようにエスケープすると意図通りの置換結果となる。

$ echo "foo=xxx" | sed "s/foo=xxx/foo=xxx\&bar=yyy/"
foo=xxx&bar=yyy

sedコマンドにおける&(アンパサンド)の意味

sedコマンドにおいて&は「マッチした文字列」に置き換わる記号。
» sed(1)

echo "abc" | sed "s/b/&/"の例の場合、bにマッチしたので&bとなり何も変わらなかったということになる。

HTTPパラメータの例(s/foo=xxx/foo=xxx&bar=yyy/)の場合は以下のような手順でfoo=xxxfoo=xxxbar=yyyとなる。

  1. foo=xxxがマッチ
  2. foo=xxx&bar=yyy&が1.でマッチしたfoo=xxxに置き換わる