我想使用grep和regex匹配一行的一部分,然后继续打印这一行和接下来的2行。但是,我不想打印任何匹配,在匹配后的第二行中,包含另一个正则表达式。
示例案文:
If the line was there is a loom in the gloom
would you want that line printed?
Just trying to understand if you're just
other than as part of gloom
if you really do want to exclude lines
even when loom appears on it's own elsewhere on the line搜索模式,;使用grep -Pn -A2 '^.*\b(gloom)\b.*$' *将打印
If the line was there is a loom in the gloom
would you want that line printed?
Just trying to understand if you're just..and
other than as part of gloom
if you really do want to exclude lines
even when loom appears on it's own elsewhere on the line但我不想在第三行打印第二个组,其中包含了这个词。使用Perl-regex。
发布于 2021-10-19 11:08:27
下面是Perl中的一个示例:
use v5.20.0; # signatures requires perl >= 5.20
use feature qw(say);
use strict;
use warnings;
use experimental qw(signatures);
{
my $lines = read_file('file.txt');
for my $i (0..$#$lines) {
my $line = $lines->[$i];
if ($line =~/\b(gloom)\b/) {
if (!match_second_pattern($lines, $i)) {
print_block($lines, $i);
}
}
}
}
sub print_block($lines, $i) {
my $N = $#$lines;
for my $j (0..2) {
last if $i+$j > $N;
print $lines->[$i+$j];
}
}
sub match_second_pattern($lines, $i) {
my $N = $#$lines;
return 0 if ($i + 2) > $N;
return $lines->[$i+2] =~ /elsewhere/;
}
sub read_file( $fn ) {
open ( my $fh, '<', $fn ) or die "Could not open file '$fn': $!";
my @lines = <$fh>;
close $fh;
return \@lines;
}发布于 2021-10-19 11:44:14
这类问题通常是用负前瞻来解决的。不幸的是,我不相信您可以让命令行grep跨行边界向前看,因此这需要一个Perl程序来完成:
#!/usr/bin/perl
use strict;
my $s = "If the line was there is a loom in the gloom
would you want that line printed?
Just trying to understand if you're just
other than as part of gloom
if you really do want to exclude lines
even when loom appears on it's own elsewhere on the line";
while ($s =~ /^.*?\bgloom\b(?!.*\n.*\n.*?\belsewhere\b).*\n.*\n.*\n?/mg) {
print "$&";
}如果希望在输入行中指定从stdin或文件输入的输入,则:
#!/usr/bin/perl -w
use strict;
my $s = '';
# read from stdin or the file specified on the command line:
while (<>) {
$s .= $_ ;
}
while ($s =~ /^.*?\bgloom\b(?!.*\n.*\n.*?\belsewhere\b).*\n.*\n.*\n?/mg) {
print "$&";
}发布于 2021-10-20 11:13:13
您可以使用GNU grep,如
grep -oPzn '(?m)^.*?\bgloom\b(?!(?:.*\R){2}.*?\belsewhere\b)(?:.*\R){2}.*\R?' file > outputfile详细信息
-o -输出匹配的文本,而不仅仅是发生匹配的行z -现在,行分隔符被删除,并且可以与regex匹配。(?m)^ -行的开始.*? -除断行字符以外的任何零或多个字符,尽可能少。\bgloom\b -全词gloom(?!(?:.*\R){2}.*?\belsewhere\b)在gloom单词下面的第二行,不应该有整个单词的elsewhere(?:.*\R){2} -当前行的其余部分、下一行和一行中断.*\R? -带可选行中断(序列)的整个(第二行)行。见在线演示
#!/bin/bash
s="If the line was there is a loom in the gloom
would you want that line printed?
Just trying to understand if you're just
other than as part of gloom
if you really do want to exclude lines
even when loom appears on it's own elsewhere on the line"
grep -oPzn '(?m)^.*?\bgloom\b(?!(?:.*\R){2}.*?\belsewhere\b)(?:.*\R){2}.*\R?' <<< "$s"https://stackoverflow.com/questions/69628776
复制相似问题