我想多次替换相同的图案 ( /g
)。该模式可以出现在单行中或跨越多行 (2+)。
例如,我想改变
EXPECT_EQ(50, var1);
EXPECT_EQ(10,
var2);
EXPECT_EQ(20,
an_expression
_that_takes
_multiple_lines);
类似的东西
EXPECT_EQ(var1, 50);
EXPECT_EQ(var2,
0);
EXPECT_EQ(an_expression
_that_takes
_multiple_lines,
20);
问题是
sed -E 's/EXPECT_EQ\(([0-9]+), (.*)\);/EXPECT_EQ(\2, \1);/g' file.txt
只会更新示例中的第一行,因为我想要的第二个匹配有 2 行。
有没有一种方法可以替换所有匹配项,而与它们有多少行无关?就像是https://regex101.com/r/QmHCyo/1但用 sed 。
结果字符串中的空格或换行无关紧要。它们可以具有任何格式,因为它们稍后会自动修复。
答案1
使用GNU sed
激活了扩展正则表达式的流编辑器实用程序-E
,我们可以执行如下操作:
sed -Ee '
/^EXPECT_EQ\(.*\);$/!{
$!N;H;z;x;D
}
s/\(([^,]+)(,\s*)(.*)\);$/(\3\2\1);/
' file
结果:-
EXPECT_EQ(var1, 50);
EXPECT_EQ(var2,
10);
EXPECT_EQ(an_expression
_that_takes
_multiple_lines,
20);
请注意,我们假设括号不是嵌套的,并且特定函数 Expect_eq 正在被修改。
目标是在模式空间中积累,直到括号平衡。之后,我们翻转用逗号和可选空格分隔的两个参数。
答案2
使用 GNU sed for-E
和-z
:
$ sed -Ez 's/(\(\s*)([^),]+\S)(\s*,\s*)([^),]+\S)(\s*\))/\1\4\3\2\5/g' file
EXPECT_EQ(var1, 50);
EXPECT_EQ(var2,
10);
EXPECT_EQ(an_expression
_that_takes
_multiple_lines,
20);