替换 sed 中的所有多行和单行匹配

替换 sed 中的所有多行和单行匹配

我想多次替换相同的图案 ( /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);

相关内容