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