grep一个模式并返回另一个特定字符bash之前和之后的所有字符

我有兴趣在日志文件中搜索变量,如果搜索返回一些内容,那么我希望在变量之前的所有条目,直到遇到字符 '{' 和模式之后,直到遇到字符 '}'。

更准确地说,让我们看下面的例子:

something something {
    entry 1
    entry 2
    name foo
    entry 3
    entry 4
}
something something test
test1 test2
test3 test4

在这种情况下,我将搜索“name foo”,它将存储在一个变量中(我之前在单独的部分中创建),预期输出将是:

{
        entry 1
        entry 2
        name foo
        entry 3
        entry 4
}

我尝试在 grep、awk 或 sed 上找到一些东西。我只能想出找到模式的选项,然后返回所有行,直到遇到 '}',但是我无法为模式之前的行找到合适的解决方案。

我在 Perl 中找到了一个可以使用的正则表达式,但我无法使用该变量,如果我用 'foo' 切换变量,那么我将有输出。

grep -Poz '.*(?s){[^}]*nametfoo.*?}'

回答

正则表达式非常简单,一旦整个文件被读入一个变量

use warnings;
use strict; 
use feature 'say';

die "Usage: $0 filenamen" if not @ARGV;

my $file_content = do { local $/; <> };  # "slurp" file with given name

my $target = qr{name foo};

while ( $file_content =~ /({ .*? $target .*? })/gsx ) { 
    say $1; 
}

由于我们使用local将do块内undef的输入记录分隔符-ine ,因此通过空文件句柄读取的以下内容立即将整个文件作为字符串(“slurps”)拉出。这是由块返回并分配给变量。在从文件(S),在名称中读取,那么什么是在程序调用上的命令行提交。<>do<>@ARGV

在正则表达式模式,?量词品牌.*仅匹配到下一个子模式的第一次出现,所以以后{.*?向上匹配到第一$target,则(评价)$target被匹配,则.*?匹配eveyrthing直至第一}。所有这些都是通过封闭捕获的(),因此以后可以在$1.

/s修改品牌.匹配换行符,它一般不会,什么是必要的,以便匹配涉及多行模式。使用/g修饰符,它会不断浏览内容。随着/x空格不匹配,所以我们可以摊开模式的可读性。

$target被编译为使用适当的正则表达式QR运营商。

请参阅正则表达式教程perlretut,然后是完整的参考perlre。


以上是grep一个模式并返回另一个特定字符bash之前和之后的所有字符的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>