如何更改" line"的定义?在grep?

时间:2017-02-20 11:09:26

标签: grep

grep将返回与特定模式匹配的文件中的行:

grep pattern file

将搜索文件并返回与 pattern 匹配的所有行。

我的代码库有许多多行语句,例如:

int x = somefunc(a,
                 b,
                 10, 
                 someclass(10),
                 foo,
                 bar);

我希望能够grep我的文件并返回整个语句,而不仅仅是行。例如,如果我希望somefunc的所有电话都使用foo,我可以这样做:

grep -e 'somefunc.*foo' filename

并获取整个函数调用,我可以将其输入另一个程序进行进一步处理:

    grep -e 'somefunc.*foo' filename | grep -v bar

基本上,我想告诉grep我的行以;而不是EOL结尾。

我无法使用-C-A-B开关,因为我不会总是知道声明中有多少行。例如,上面的例子可以写成:

int x = somefunc(a, b,
                 10, someclass(10),
                 foo, bar);

有没有办法用grep或任何其他常用工具执行此操作?

4 个答案:

答案 0 :(得分:1)

您可以使用awk更改RECORD / LINE的定义。 RS默认设置为新行,您可以根据需要进行更改。在以下示例中,RS更改为;。以下行将在" 代码记录中搜索someclass2字符串,该记录以;"

结尾

awk命令:

awk -v RS=';' '/someclass2/' input

示例:

awk -v RS=';' '/someclass2/' input
int x = somefunc(a,
                 b,
                 10,
                 someclass2(10),
                 foo,
                 bar)

以下是使用的输入文字:

cat input
int x = somefunc(a,
                 b,
                 10,
                 someclass0(10),
                 foo,
                 bar);

int x = somefunc(a,
                 b,
                 10,
                 someclass1(10),
                 foo,
                 bar);

int x = somefunc(a,
                 b,
                 10,
                 someclass2(10),
                 foo,
                 bar);

答案 1 :(得分:0)

好吧,做你说的话。将;更改为\n,将\n更改为;,执行grep,然后再将其更改回来。

re=$1
cat "$@" | # tr only reads from stdin
    tr '\n;' ';\n' |
    grep -- "$re" |
    tr '\n;' ';\n'

答案 2 :(得分:0)

假设我们有一个文件test_grep,内容为:

int x = somefunc(a,
                 b,
                 10,
                 someclass(10),
                 foo,
                 bar);

float y = 2

int z  = somefunc(a, b,
                 10, someclass(10),
                 foo, bar);

float w = 4
grep -Pzo  '(?s)somefunc\(.*?foo.*?\);' test_grep

P - 允许Perl定期表达

z - 在行尾压缩换行符,将其替换为空字符。

o - 仅输出匹配的部分

(?s) - PCRE_DOTALL模式,将.视为任何字符或换行符

输出(对于上面的例子):

somefunc(a,
                 b,
                 10, 
                 someclass(10),
                 foo,
                 bar);
somefunc(a, b,
                 10, someclass(10),
                 foo, bar);

答案 3 :(得分:0)

当然, perl 单线程符合这个要求。

# 1
  • perl -00 -nE 'say $& while /somefunc.*?foo/sg' file Pragraph模式。 Perl 以空行分隔的块读取文件。
  • -00遍历每个阅读段落
  • -n脚本在命令行上跟随
  • -E此正则表达式修饰符将模式/s的定义扩展为包含* . 正则表达式 while / /gwhile组合在找到第一个匹配后查找段落中的另一个匹配项。如果您只想要第一场比赛,则可能更喜欢/g 新行
  • if是一个正则表达量词,意味着尽可能少。不要使用*?,并且尽可能多地将?表示 。不是你真的想要的。
  • *扩展到最后匹配的正则表达式