Answers:
如果StringB
和StringA
不能出现在同一输入行上,则可以告诉sed以一种方式执行替换,并且如果没有第一个搜索到的字符串出现,则只能尝试另一种方式。
<file.txt sed -e 's/StringA/StringB/g' -e t -e 's/StringB/StringA/g'
在一般情况下,我认为sed中没有简单的方法。顺便说一句,注意,规格是,如果不明确StringA
和StringB
可以重叠。这是一个Perl解决方案,它替换了两个字符串中最左边的一个,然后重复执行。
<file.txt perl -pe 'BEGIN {%r = ("StringA" => "StringB", "StringB" => "StringA")}
s/(StringA|StringB)/$r{$1}/ge'
如果您要坚持使用POSIX工具,则可以使用awk。Awk没有用于常规参数化替换的原语,因此您需要自己滚动。
<file.txt awk '{
while (match($0, /StringA|StringB/)) {
printf "%s", substr($0, 1, RSTART-1);
$0 = substr($0, RSTART);
printf "%s", /^StringA/ ? "StringB" : "StringA";
$0 = substr($0, 1+RLENGTH)
}
print
}'
-e
在第二条s
命令之前没有任何内容。我已经解决了。
现在,我正在做类似
......
的问题…… 这种方法的问题在于,它假定StringC没有出现在文件中。
我认为您的方法很好,您应该只使用其他东西而不是字符串,这是不可能在一行(模式空间)中发生的。最佳人选是\n
腰线。
通常,模式空间中的任何输入行都不会包含该字符,因此,要交换文件中THIS
和的所有出现THAT
,可以运行:
sed 's/THIS/\
/g
s/THAT/THIS/g
s/\n/THAT/g' infile
或者,如果您的sed也支持\n
RHS:
sed 's/THIS/\n/g;s/THAT/THIS/g;s/\n/THAT/g' infile
sed
如果事先准备好一些宏,是否支持某些转义就变得不那么重要了。像set /THIS /THAT "$(printf \\n/)"; sed "s/$2/\\$4g;s/$3$2/g;s/\\n$3/g"
-有点笨这里,不可否认,但它使很多更有意义,当一些其他时间-尤其是对于焦炭类和类似。
sed
,否则持续不断的分叉开销e
就是种恶梦。另一方面,我已经玩paste
了整整一天。我做了一个选项解析器- column
有点像。它只是将输入字符串和字符串填充在一起的破折号。
我认为使用“ nonce”字符串交换两个单词是完全有效的。如果您想要更一般的解决方案,可以执行以下操作:
sed 's/_/__/g; s/you/x_x/g; s/me/you/g; s/x_x/me/g; s/__/_/g' <<<"say you say me"
那产生
say me say you
请注意,x_x
如果您碰巧有“ x_x”字符串,则需要在此处另外两个替换项来避免替换。但是即使那样,这似乎仍然比awk
我的解决方案简单。
_
,则需要调整_
自身(选择另一个字符)或麻烦的字符串(s/_/__/g
事先对其执行,似乎更好)。实际上,您的解决方案不能盲目地应用于交换任意字符串。
s/_/__/g
事先申请的。也许只是显示一个失败的测试用例。
_
,所以说更换y_ou
用me
。是的,确实是必须要意识到这一点并将其放入y__ou
表达式中。将替换作为输入参数的脚本也必须考虑到这一点。
sed: can't read s/StringB/StringA/g: No such file or directory
。似乎-e t PATTERN
还不太了解。