Text-Processing

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

  • November 12, 2016

請幫我解決以下問題。\ 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 的參數可以嵌套呼叫其他宏,並且可以在字元串中包含任何字元。

有句話要記住,“正則表達式算不上”。

這在這種情況下很重要,因為許多“簡單”的 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 之類的工具之上建構工具。

編輯:這個答案是在修改問題之前準備好的。問題的原始形式包括:

當我嘗試使用“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");
$ 

引用自:https://unix.stackexchange.com/questions/319190