用sed替换包含&符号的url

时间:2017-09-07 20:47:08

标签: bash shell sed

我以前使用sed替换了url,之前没有问题。然而,这个网址给我带来了麻烦。它有相当多的&符号,我需要更换它们。我该怎么做呢?

sed -i.bak "s#<string>https://www.url1toreplace.com?blah=1234585474738743874386328764287364238746283764287346872364fN&amp;blah=Y&amp;blah=%2Fwebapp%2Fwcs%2Fblahblah%2Fblah%2Fen%2Fblahahah%3Fblah%3e212e123152%26cm_mmc%3DBLAH-_-BLAH-_-Null-_-Null</string>#<string>https://www.urltoreplace.com/blah/blah/blah/blah/en/blah?blah=129i312093132&cm_mmc=BLAH-_-BLAH-_-Null-_-Null</string>#g" path/to/xml/file

我的问题是它没有完全替换网址。如何逃离&符号,以便我可以通过www.urltoreplace.com成功替换www.url1toreplace.com以及随后的所有内容?

2 个答案:

答案 0 :(得分:2)

在替换文字中,您需要转义&

例如,没有转义符,每个&都会替换整个原始匹配:

$ echo '&amp;' | sed 's#&amp;#a & b & c#'
a &amp; b &amp; c

通过转义,\&&被视为普通字符:

$ echo '&amp;' | sed 's#&amp;#a \& b \& c#'
a & b & c

你的例子

我们来看看这个测试文件:

$ cat file
<string>https://www.url1toreplace.com?blah=1234585474738743874386328764287364238746283764287346872364fN&amp;blah=Y&amp;blah=%2Fwebapp%2Fwcs%2Fblahblah%2Fblah%2Fen%2Fblahahah%3Fblah%3e212e123152%26cm_mmc%3DBLAH-_-BLAH-_-Null-_-Null</string>

运行原始命令:

$ sed "s#<string>https://www.url1toreplace.com?blah=1234585474738743874386328764287364238746283764287346872364fN&amp;blah=Y&amp;blah=%2Fwebapp%2Fwcs%2Fblahblah%2Fblah%2Fen%2Fblahahah%3Fblah%3e212e123152%26cm_mmc%3DBLAH-_-BLAH-_-Null-_-Null</string>#<string>https://www.urltoreplace.com/blah/blah/blah/blah/en/blah?blah=129i312093132\&cm_mmc=BLAH-_-BLAH-_-Null-_-Null</string>#g" file
<string>https://www.urltoreplace.com/blah/blah/blah/blah/en/blah?blah=129i312093132&cm_mmc=BLAH-_-BLAH-_-Null-_-Null</string>

上述命令失败。但是,如果我们逃离&,我们会得到:

$ sed 's#<string>https://www.url1toreplace.com?blah=1234585474738743874386328764287364238746283764287346872364fN&amp;blah=Y&amp;blah=%2Fwebapp%2Fwcs%2Fblahblah%2Fblah%2Fen%2Fblahahah%3Fblah%3e212e123152%26cm_mmc%3DBLAH-_-BLAH-_-Null-_-Null</string>#<string>https://www.urltoreplace.com/blah/blah/blah/blah/en/blah?blah=129i312093132\&cm_mmc=BLAH-_-BLAH-_-Null-_-Null</string>#g' file
<string>https://www.urltoreplace.com/blah/blah/blah/blah/en/blah?blah=129i312093132&cm_mmc=BLAH-_-BLAH-_-Null-_-Null</string>

此操作成功:替换字符串中的&成功显示在输出中。

答案 1 :(得分:1)

示例数据文件:

$ cat xfile
<string>https://www.old.home.com?x=123&amp;y=abc&amp;z=ABC_mmc%3D</string>

期望的输出:

<string>https://www.new.home.biz?A=XYZ&amp;B=123&amp;C=987_jjj%2XD</string>

正如John1024已经指出的那样,如果sed替换字符串包含&,则&必须被转义( \&)(因为&sed具有特殊含义。

嗯,但如果你必须通过并且(手动?)将所有sed替换模式从&更改为\&,那么这可能是主要的痛苦。但这种替代可以通过一些小的假设自动化......

假设:

  • 搜索和替换模式可以分别存储在变量beforeafter中(实际上,只需要after变量就可以使这个想法起作用,但是对于这个例子我可以#&# 39; ll使用beforeafter变量)
  • beforeafter包含正常的字符串,没有任何特殊的转义
  • 您的bash版本通过${var// /}构建
  • 支持字符替换

动态地将转义应用于after变量:

$ before='old.home.com?x=123&amp;y=abc&amp;z=ABC_mmc%3D'

$ after='new.home.biz?A=XYZ&amp;B=123&amp;C=987_jjj%2XD'

$ sed "s#${before}#${after//\&/\\\&}#g" xfile

<string>https://www.new.home.biz?A=XYZ&amp;B=123&amp;C=987_jjj%2XD</string>
  • ${after//\&/\\\&}:在after变量中,将所有&替换为\&

这样就无需通过并手动转义替换字符串中出现的所有&