查找模式並將其從所有文件中刪除
請幫我解決以下問題。
\
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"); $