尋找模式並將其從所有文件中刪除

尋找模式並將其從所有文件中刪除

請幫我解決以下問題。\ 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...

目錄1/檔案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...

目錄1/檔案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 可以循環。

這是一個 Sed 片段,它將從任何包含Test_Macro到具有適當右括號的行中抓取,即使有嵌套的括號:

#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...

相關內容