如何在匹配之前和之后打印行直到特定匹配(3 个匹配模式)

时间:2021-03-19 11:12:19

标签: awk sed grep text-processing

我有一个很长的数据,它是用块构建的。

在下面的示例中,让我们看到它们以 (AAA) 开头并以 (FFF) 结尾,它们之间可以有很多行信息

我想提取特定的块,前提是模式 (CCC) 在这些块内。

一个例子是:

cat text
AAA1
BBB
FFF1
AAA2
BBB
CCC2
DDD
EEE
FFF2
AAA3
BBB
FFF3
AAA4
BBB
CCC4
DDD
EEE
FFF4

输出应该是:

AAA2
BBB
CCC2
DDD
EEE
FFF2
AAA4
BBB
CCC4
DDD
EEE
FFF4

我想过使用 sed,但没有真正起作用: 如果使用这只会让我从 CCC 到下一个 AAA/FFF:sed -n -e '/CCC/,/AAA/ p' textsed -n -e '/CCC/,/AAA/ p' text

CCC2
DDD
EEE
FFF2
AAA3
CCC4
DDD
EEE
FFF4

如果我这样使用它:sed -n -e '/AAA/,/FFF/ p' text 我将捕获 AAA 和 FFF 之间没有 CCC 的模式。

4 个答案:

答案 0 :(得分:4)

这可能对你有用(GNU sed):

sed -n '/AAA/{:a;N;/FFF/!ba;/CCC/p}' file

关闭隐式打印-n,因为这是一个过滤操作。

匹配包含 AAA 的行并附加更多行直到包含 FFF 的行。

如果集合包含字符串 CCC,则打印它。

重复。

注意这假设 AAAFFF 是配对的,如果不使用:

sed -n '/AAA/{:a;N;/\n.*AAA/s/.*\n//;/FFF/!ba;/CCC/p}' file

替代方案:

sed -n 'H;/AAA/h;/FFF/{g;/AAA.*CCC/p;z;h}' file

编辑:

对于行首的 AAACCCFFF,使用:

sed -n '/^AAA/{:a;N;/^FFF/M!ba;/^CCC/Mp}' file

sed -n '/^AAA/{:a;N;/\nAAA/s/.*\n//;/\nFFF/!ba;/\nCCC/p}' file

sed -n 'H;/^AAA/h;/^FFF/{g;/AAA.*\nCCC/p;z;h}' file

答案 1 :(得分:3)

在每个 Unix 机器上的任何 shell 中使用任何 awk:

constructor(
    private route: ActivatedRoute,
    private router: Router,
    private location: Location
    ) {      
      this.router.events.pipe(takeUntil(this.destroyed$)).subscribe((event) => {
        if (event instanceof NavigationStart) {
          console.log('router: ', router);
          console.log('event: ', event);      
          console.log('location: ', location);
        }
      }
  }

答案 2 :(得分:1)

您可以将输入视为数据块,AAA.* 作为开始标签,FFF.* 作为结束标签。现在将每个块收集到保持空间中,并在结束标记处检查该块是否包含所需的模式。

例如,这是执行此操作的 GNU sed 版本:

parse.sed

# Start-tag -> start a new block in hold-space
/^AAA/ { h; b; }

# Save input
H

# End-tag AND block contains CCC -> print
/^FFF/ { x; /\nCCC/ p; }

像这样运行,例如:

sed -nf parse.sed | sed '/^FFF/G'

或者作为单线:

sed -n '/^AAA/{h;b};H;/^FFF/{x;/\nCCC/p}' | sed '/^FFF/G'

输出:

AAA2
BBB
CCC2
DDD
EEE
FFF2

AAA4
BBB
CCC4
DDD
EEE
FFF4

更便携的 sed 脚本如下所示:

# Start-tag -> start a new block in hold-space
/^AAA/ { 
  h
  b
}

# Save input
H

# End-tag AND block contains CCC -> print
/^FFF/ { 
  x
  /\nCCC/p
}

答案 3 :(得分:0)

awk 变体

awk '/^AAA/{f=1} f{i=i $0 ORS} /^FFF/{if(i~/\nCCC/){printf "%s", i} i=f=""}' input
相关问题