查找模式并将其从所有文件中删除

查找模式并将其从所有文件中删除

请帮我解决以下问题。\ 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...

相关内容