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。