パターンを見つけてすべてのファイルから削除する

パターンを見つけてすべてのファイルから削除する

\ n次の問題の解決を手伝ってください。すべてのファイルの Test_Macro からすべての文字のペアを削除します。以下の例を参照してください。

ファイル1.txt

Test_Macro(abc, def, "\n string1 string2 \n test string",
       "test string2 \n");
// Some code or text

Test_Macro(asdsadas, "test String1");
// Some code...

dir1/ファイル2.txt

Test_Macro(abc, def, "\n string1 string2 \n test string",
       "test string2 \n",
        123456);
// Some code or text

Test_Macro(asdsadas, "test String1");
// Some code...

期待される結果:

ファイル1.txt

Test_Macro(abc, def, " string1 string2 test string",
   "test string2 ");
// Some code or text

Test_Macro(asdsadas, "test String1");
// Some code...

dir1/ファイル2.txt

Test_Macro(abc, def, " string1 string2  test string",
   "test string2 ",
    123456);
// Some code or text

Test_Macro(asdsadas, "test String1");
// Some code...

どのような助言や提案でも大歓迎です。スクリプトをいくつか書こうと思っています。さまざまな種類のファイルと、そのようなマクロがたくさんあるからです。よろしくお願いします!

Test_Macro への引数には、他のマクロへのネストされた呼び出しを含めることができ、文字列内に任意の文字を含めることができます。

答え1

覚えておくべきフレーズがあります。「正規表現はカウントできません」。

この場合、多くの「単純な」UNIXツールが正規表現に基づいているため、これが重要になります。ここでのカウントは、Test_Macro への引数内で使用される可能性のある開き括弧と閉じ括弧 (「丸括弧」) をカウントすることです。

Test_Macroの呼び出しの場合一度もない括弧がネストされている場合は、簡単なトリックがあります。まず、すべての)文字を改行に変更し、その逆も行います。次に、Test_Macro を含まないすべての行を削除し、Test_Macro までのすべてを削除します。この時点で、処理された File2.txt の一部は次のようになります。

Test_Macro(abc, def, " string1 string2 test string",)   "test string2 ",)    123456

では、 を)元に戻します。この時点では、いくつかのオプションがあります。私は、余分なスペースを同時に取り除くために sed を使うことを好みます。また、 を元に戻し、)おそらく も追加する必要があります。;

これらをまとめると、

find . -type f | while read -r fn
do
   < "$fn" tr ')\n' '\n)' | sed -n 's/.*Test_Macro(/Test_Macro(/p' | \
     sed 's/) */ /g;s/$/);/'
done

Test_Macro への引数にネストされた括弧が含まれる可能性がある場合は、パターン マッチだけでなく入力を解析する必要があるため、かなり強力な武器を使用する必要があります (理論上は、ネスト レベルを制限できればパターン マッチが可能ですが、実際にはすぐに非常に複雑になるため、このアプローチは避けるべきです)。Python などの言語用のパーサー フレームワークがあります。また、lex などのツールの上にツールを構築することもできます。

答え2

編集: この回答は質問が修正される前に作成されました。質問の元の形式には以下が含まれていました:

「grep」を使用してパターンを検索しようとすると、最初の行のみが出力されます。しかし、括弧の最後まで出力したいのです。

正規表現ではカウントできませんが、Sed ではループできます。

Test_Macro以下は、適切な閉じ括弧を含む行からその行までを取得するSedスニペットです。括弧がネストされている場合でも、

#n
/Test_Macro/{
  p;
  :rep
  s/([^()]*)//;
  trep
  /^[^(]*$/d;
  h;
  n;
  p;
  x;
  G;
  brep
}

これをワンライナーに変換すると、次のようになります。

sed -n -e '/Test_Macro/{p;:rep' -e 's/([^()]*)//;trep' -e '/^[^(]*$/d;h;n;p;x;G;brep' -e '}'

入力と出力は次のようになります。

$ cat temp 
Test_Macro(abc, def, "\n string1 string2 \n test string",
       "test string2 \n");
// Some code or text

Test_Macro(asdsadas, "test String1");
// Some code...
$ sed -n -e '/Test_Macro/{p;:rep' -e 's/([^()]*)//;trep' -e '/^[^(]*$/d;h;n;p;x;G;brep' -e '}' temp 
Test_Macro(abc, def, "\n string1 string2 \n test string",
       "test string2 \n");
Test_Macro(asdsadas, "test String1");
$ 

答え3

ファイル1:

$ sed '/Test_Macro/{N;$!N;s/.*\(Test_Macro[^)]*);\).*/\1/;p;};d' abc.txt
Test_Macro(abc, def, "\n string1 string2 \n test string",
       "test string2 \n");
Test_Macro(asdsadas, "test String1");

ファイル2:

$ sed '/Test_Macro/{N;$!N;s/.*\(Test_Macro[^)]*);\).*/\1/;p;};d' abc2.txt
Test_Macro(abc, def, "\n string1 string2 \n test string",
       "test string2 \n",
        123456);
Test_Macro(asdsadas, "test String1");

ps、すべての改行を削除する最も簡単な方法は次のとおりです。

echo -e "line \n break" | tr "\n" " "

改行なし

$ sed ':a;N;$!ba;s/[^;]\n[ ]*/ /g;' abc2.txt  | grep Test_Macro
Test_Macro(abc, def, "\n string1 string2 \n test string" "test string2 \n" 123456);
Test_Macro(asdsadas, "test String1");

「\n」なしで改行あり...笑

$ sed '/Test_Macro/{N;$!N;s/[ ]*\\n//g;s/.*\(Test_Macro[^)]*);\).*/\1/;p;};d' abc2.txt
Test_Macro(abc, def, " string1 string2 test string",
       "test string2",
        123456);
Test_Macro(asdsadas, "test String1");

「\n」文字列(および末尾のスペース)を削除するだけです。

$ sed ':a;N;$!ba;s/\\n[ ]*//g;' abc2.txt
Test_Macro(abc, def, "string1 string2 test string",
       "test string2 ",
        123456);
// Some code or text

Test_Macro(asdsadas, "test String1");
// Some code...

もう一度 (できればこれが最後)... 関数 Test_Macro 内では文字列 "\n" を削除しますが、関数外では削除せず、改行も削除しません。

$ sed '{N;/Test_Ma/{s/[ ]*\\n//g;};s/\(Test_Macro[^)]*);\)/\1/};' abc2.txt
Test_Macro(abc, def, " string1 string2 test string",
       "test string2",
        123456);
// Some code or text \n

Test_Macro(asdsadas, "test String1");
// Some code...

アップデート;

$ sed '{:a;N;/Test_Ma/{s/[ ]*\\n//g;};ta};' abc2.txt 
Test_Macro(abc, def, " string1 string2 test string",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
       "test string2",
        123456);
// Some code or text \n
// Some code or text \n
// Some code or text \n
// Some code or text \n
// Some code or text \n
// Some code or text \n
// Some code or text \n
// Some code or text \n
// Some code or text \n
// Some code or text \n

Test_Macro(asdsadas, "test String1");
// Some code...

関連情報