[英]Is sed auto in-place substitution?
我有此代码,我想替换特定的模式,但不希望进行多次就地替换。
echo "ss qq" | sed "s/ss/qq/g; s/qq/dd/g;"
结果是
dd dd
并希望是
qq dd
同样通过“循环”,我们得到相同的结果。
echo "ss qq" | sed ":loop; s/ss/qq/g; s/qq/dd/g; t loop;"
它的小巧,非常令人失望的错误!
有什么建议为什么会发生吗?
至于“为什么发生”:sed逐行输入输入,然后依次应用每个命令。 如果查看命令的GNU sed(4.6或更高版本)的调试输出,这将变得更加清楚:
$ sed --debug 's/ss/qq/g;s/qq/dd/g' <<< 'ss qq'
SED PROGRAM:
s/ss/qq/g
s/qq/dd/g
INPUT: 'STDIN' line 1
PATTERN: ss qq # Pattern space before first command is applied
COMMAND: s/ss/qq/g
MATCHED REGEX REGISTERS
regex[0] = 0-2 'ss'
PATTERN: qq qq # Pattern space before second command is applied
COMMAND: s/qq/dd/g
MATCHED REGEX REGISTERS
regex[0] = 0-2 'qq'
PATTERN: dd dd
END-OF-CYCLE:
dd dd
希望如此
qq dd
然后您以相反的顺序进行替换:
更改sed "s/ss/qq/g;s/qq/dd/g;"
-> sed "s/qq/dd/g;s/ss/qq/g;"
也许是您要查找的y///
命令的行为:
▶ echo "ss qq" | sed 'y/sq/qd/'
qq dd
这将一个字符一个字符地将所有s
转换为q
,将所有q
转换为d
。
这可能对您有用(GNU sed):
sed 's/ss\|qq/\n&/;:a;s/\nss/qq\n/;s/\nqq/dd\n/;s/\n\(.\)/\1\n/;ta;s/\n//' file
这将以换行符的形式引入有关最后替换发生位置的标记。 在该行的末尾,标记被删除。
使用该标记的原因是因为每次替换命令的调用均从该行的开头重新开始,而不是从最后一次替换结束的地方开始。 g
标志可能会使问题感到困惑,但仅属于替换的当前调用。
如前所述,更好的方法是对第一个替换使用替代方法,并将其全局替换为最后一个命令。
sed 's/ss/\n/g;s/qq/dd/g;s/\n/qq/g' file
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.