我以前使用sed替换了url,之前没有问题。然而,这个网址给我带来了麻烦。它有相当多的&符号,我需要更换它们。我该怎么做呢?
sed -i.bak "s#<string>https://www.url1toreplace.com?blah=1234585474738743874386328764287364238746283764287346872364fN&blah=Y&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以及随后的所有内容?
答案 0 :(得分:2)
在替换文字中,您需要转义&
。
例如,没有转义符,每个&
都会替换整个原始匹配:
$ echo '&' | sed 's#&#a & b & c#'
a & b & c
通过转义,\&
,&
被视为普通字符:
$ echo '&' | sed 's#&#a \& b \& c#'
a & b & c
我们来看看这个测试文件:
$ cat file
<string>https://www.url1toreplace.com?blah=1234585474738743874386328764287364238746283764287346872364fN&blah=Y&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&blah=Y&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&blah=Y&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&y=abc&z=ABC_mmc%3D</string>
期望的输出:
<string>https://www.new.home.biz?A=XYZ&B=123&C=987_jjj%2XD</string>
正如John1024已经指出的那样,如果sed
替换字符串包含&
,则&
必须被转义( \&
)(因为&
对sed
具有特殊含义。
sed
替换模式从&
更改为\&
,那么这可能是主要的痛苦。但这种替代可以通过一些小的假设自动化......
假设:
before
和after
中(实际上,只需要after
变量就可以使这个想法起作用,但是对于这个例子我可以#&# 39; ll使用before
和after
变量)before
和after
包含正常的字符串,没有任何特殊的转义bash
版本通过${var// /}
构建动态地将转义应用于after
变量:
$ before='old.home.com?x=123&y=abc&z=ABC_mmc%3D'
$ after='new.home.biz?A=XYZ&B=123&C=987_jjj%2XD'
$ sed "s#${before}#${after//\&/\\\&}#g" xfile
<string>https://www.new.home.biz?A=XYZ&B=123&C=987_jjj%2XD</string>
${after//\&/\\\&}
:在after
变量中,将所有&
替换为\&
这样就无需通过并手动转义替换字符串中出现的所有&
。