有没有一种方法可以使用sed进行多次替换,而不必链接替换?
我想编写一个shell脚本,用BB替换a,用AA替换B。例如,AYB变成BBYAA。我通常的解决方法是将多个调用链接到sed,比如本:sed's/A/BB/g;s/B/AA/g'然而,这在这种
解答动态
这是一种需要循环的问题,因此可以同时搜索两种模式。
awk'BEGIN{regex=";aBquot;aquot;BBquot;Bquot;AAquot;while(match(str,regex)){found=substr(str,RSTART,RLENGTH)result=result substr(str,1,RSTART-1)map[found]str=substr(str,RSTART+RLENGTH)}print result str}的 当然,如果Perl可用,还有一个等价的一行:
perl-pe'开始{%map=(quot;=quot;BBquot;Bgt;quot;);}s/(AB)/$map{$1}/g;' 如果没有任何模式包含特殊字符,您还可以构建regex dy名称:
perl-pe'开始{%map=(quot;=quot;BBquot;Bgt;quot;);$regex=join";";,键%map;}s/($regex)/$map{$1}/g;' 顺便说一句,Tcl有一个内置的命令,这个命令叫做string map,但是编写Tcl oneliners并不容易。
在sed中用一个替换不能完成整个操作,但根据两个子字符串A和B是单个字符还是更长的字符串,您可以用不同的方法正确地执行此操作。
假设两个子字符串A和B是单个字符…
您要将AYB转换为BBYAA。为此,
使用y/AB/BA/将每个A更改为B,并将每个B更改为A。使用s/A/AA/g将新字符串中的每个A替换为AA。使用s/B/BB/g将新字符串中的每个B替换为BB。 $echo AYBsed'y/AB/BA/;s/B/BB/g;s/A/AA/g'bbyaa 将最后两个步骤结合起来,得到
$echo AYBsed'y/AB/BA/;s/[AB]/&;/g'bbyaa 事实上这里的行动并不是真的物质:
$echo AYBsed的/[AB]/amp;/g将加倍输入数据中的任何A或B字符。
对于多字符子字符串,假定子字符串是不同的(即,在另一个子字符串中找不到一个子字符串,与oo和foo的情况一样,使用类似于
$echo fooxbarsed's/foo/@/g;s/bar/foofoo/g;s/@/barbar/g'barbarxfoo i的内容。例如,通过在数据中找不到的中间字符串交换这两个字符串。请注意,中间字符串可以是数据中找不到的任何字符串,而不仅仅是单个字符。
对于awk,可以使用pattern1作为字段分隔符FS,replacement1作为输出字段分隔符OFS。然后,在每个字段上循环并用replacement2替换pattern2:
awk'{for(f=1;f<;=NF;f++){gsub(p,r,$f)}$1=$1}1'FS=A OFS=BB p=B r=AA file $1=$1的要点是强制重新生成记录,否则它将失败,例如0A。
这是POSIX兼容的,不涉及中间字符串,因此它是万无一失的。
我认为一种解决方案是用第一个A或B替换字符串中不存在的另一个字符,然后替换该字符。这样就避免了A和B之间的切换。虽然一系列的sed需要:
$echo AYBsed-e's/A/#/g'-e's/B/AA/g'-e's/#/BB/g'BBYAA
使用GNU sed可以通过将all As更改为记录分隔符来完成此操作,该分隔符肯定不会出现。
echo AYBsed-e'y/A/\n/s/[\nB]/&;/g y/\nB/BA/'BBYAA
如果它使用的不是sed或tr.
Dyalog APL的?R(quot;)PCRE替换操作符(完整文档)也可以匹配:
模式←?JSON'[“A”、“B”]'替换←?JSON'[“BB”、“AA”;]'转换←模式?R替换?←转换? 在线试用!
在上面,为了清晰起见,我已经详细说明了所有内容,但是要创建一个这样做的函数,您只需要需要:
(,¨'AB')?R'BB''AA' 在TryAPL上试一试!第2页- End
免责声明:
本页内容仅代表作者本人意见,若因此产生任何纠纷由作者本人负责,概与琴岛网公司无关。本页内容仅供参考,请您根据自身实际情况谨慎操作。尤其涉及您或第三方利益等事项,请咨询专业人士处理。