sed で複数行と 1 行一致の両方を置き換えます。

sed で複数行と 1 行一致の両方を置き換えます。

/g同じパターン()を何度も交換したいと思います。パターンは 1 行に表示することも、複数行 (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番目の一致に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つのパラメータを反転します。

答え2

-E次にGNU sedを使用してください-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);

関連情報