如何在 grep 中搜索多个模式,同时忽略连续出现的第一个模式

如何在 grep 中搜索多个模式,同时忽略连续出现的第一个模式

我有如下输入。我想找出以之间的行开头abc和结尾的所有mno内容,但如果在来abc之前再次出现mno,那么我想忽略第一个匹配的abc.我的想法是,我只需要一个以彼此最接近的开头abc和结尾的组。mno

test.txt文件包含以下数据:

ABC
bbb
ABC
yyy
米诺
ABC
xxx
米诺

预期输出:

ABC
yyy
米诺
ABC
xxx
米诺

我正在使用下面的grep衬里:

grep -ozP  "(?s)(abc).\*?(mno)" test.txt

结果是:

ABC
bbb
ABC
yyy
米诺
ABC
xxx
米诺

前两行不应出现在输出中。请告知我可以修改哪些内容grep以获得所需的结果。

答案1

解决此问题的一种方法是使用tac, find matches来反转文件开始mno结尾abc,然后反转以获得所需的结果。我有以下工作:

$ tac test.txt | pcregrep -M 'mno(\n|.)*?abc' | tac
abc
yyy
mno
abc
xxx
mno

(我用于pcregrep多行-M标志)

答案2

以防万一 perl 适合你:

#!/usr/bin/env perl
# saved lines to print out
my @out = ();
# should we save lines?
my $saving = 0;
while (<>) {
  if (/abc/) {
    if ($saving) {
      # this is the second /abc/, so dump what we were saving and start over
      @out = ($_);
    } else {
      # this is the first /abc/, so save it and start saving lines
      push @out, $_;
      $saving = 1;
    }
  } elsif (/mno/) {
    if ($saving) {
      # print what we've saved, plus this /mno/ ending line, then reset
      print @out, $_;
      @out=();
      $saving=0;
    }
  } else {
    # otherwise, save lines if we should be
    push @out, $_ if $saving;
  }
}

答案3

grep -ozP  "(?s)(abc)[^(abc)]*(mno)" 1
abc
yyy
mno
abc
xxx
mno

相关内容