我如何更改“的定义?”;“行”;在grep?

我如何更改“的定义?”;“行”;在grep?,grep,Grep,grep将返回文件中与特定模式匹配的行: grep模式文件 将搜索整个文件并返回所有匹配模式的行 我的代码库有许多多行语句,例如: int x = somefunc(a, b, 10, someclass(10), foo, bar); 我希望能够grep我的文件并返回整个语句,而不仅仅是行。例如,如果我希望所有使用foo的

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

grep模式文件

将搜索整个文件并返回所有匹配模式的行

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

int x = somefunc(a,
                 b,
                 10, 
                 someclass(10),
                 foo,
                 bar);
我希望能够
grep
我的文件并返回整个语句,而不仅仅是行。例如,如果我希望所有使用
foo
somefunc
调用,我可以执行以下操作:

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或其他常用工具来做到这一点?

好吧,照你说的去做。更改
\n
\n
,执行grep,然后再次更改它们

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

假设我们有一个文件
test\u 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

p
-允许Perl正则表达式

z
-在行尾抑制换行符,将其替换为空字符

o
-仅输出匹配的零件

(?s)
-
PCRE\u DOTALL
模式,将
视为任何字符或换行符


输出(对于上述示例):

当然,perl one liner适合这里

perl -00 -nE 'say $& while /somefunc.*?foo/sg' file
  • -00
    Pragraph模式。Perl以由空行分隔的块读取文件
  • -n
    在每个阅读段落上循环
  • -E
    脚本位于命令行上
  • /s
    此正则表达式修饰符扩展了模式
    的定义,以包括*
    while/
    正则表达式
    while
    /g
    组合在找到第一个匹配项后在段落中查找另一个匹配项。如果只需要第一个匹配项,您可能会选择
    if
    新行
  • *?
    是一个正则表达式量词,表示尽可能少。去掉
    ,不加修饰的
    *
    意味着尽可能多。这不是你想要的
  • $&
    扩展到最后匹配的正则表达式所匹配的内容

您可以使用
awk
更改记录/行的定义
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);

嗨,内森,请你接受以下最适合你要求的答案吗?我试过了,但没有一个是真正令人满意的
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);