查找两个模式之间的所有线条,第二个模式独有的?

查找两个模式之间的所有线条,第二个模式独有的?

考虑一下我有下面列出的文件。我需要从正则表达式模式的每个实例中选择所有Word A正则表达式模式Word D

Word A
Word B
Word C
Word D
Word E
Word F
Word G
Word A
Word H
Word I
Word D
Word J
Word A
Word K
Word D
Word L
Word M
Word A
Word D

A请注意和之间的可变行数D。有时,D是下一行。这就是我需要的输出:

Word A
Word B
Word C
Word A
Word H
Word I
Word A
Word K
Word A

可以使用 awk、perl、python 或 sed 完成。只要安装在该文件所在的 RHEL6 服务器上就没有关系。

答案1

使用 AWK:

awk '/Word A/ { m = 1 } /Word D/ { m = 0 } m'

答案2

这是一个awk解决方案

awk \
  -vstart='Word A' \
  -vend='Word D' \
  '{
     if ($0==end  ) {flag=0;next};
     if ($0==start) {flag=1};
     if (flag==1) {print $0};
  }'

正则表达式处理只需稍作更改

awk \
  -vstart='Word[ ]A' \
  -vend='Word[ ]D' \
  '{
     if ($0 ~ end  ) {flag=0;next};
     if ($0 ~ start) {flag=1};
     if (flag==1) {print $0};
  }'

答案3

使用(以前称为 Perl_6)

~$ raku -ne '.put if / Word \h A / fff^ / Word \h D /;'  file

Raku 是 Perl 家族的一种编程语言。它是一种“富含运算符”的语言,具有强大的正则表达式引擎。上面,-ne使用了非自动打印逐行标志,与 Raku 的类似 sed 的fff“触发器”运算符结合使用。

Raku 包含其类似 sedfff中缀运算符的各种“风格”,包括fff^,^fff甚至^fff^.当每个正则表达式被识别时,^插入符号指示应从输出中删除已识别的行:

输入示例:

Word A
Word B
Word C
Word D
Word E
Word F
Word G
Word A
Word H
Word I
Word D
Word J
Word A
Word K
Word D
Word L
Word M
Word A
Word D

示例输出:

Word A
Word B
Word C
Word A
Word H
Word I
Word A
Word K
Word A

上面的代码解决了OP的测试用例。但是如果/start//stop/Regexes 实际上在同一行怎么办?对于这个问题,你可以尝试 Raku 的类似 awk 的ff运算符:

~$ echo 'AB\nCD\nEF' | raku -ne 'say $_ if /A/ ff /B/;'
AB
~$ echo 'AB\nCD\nEF' | raku -ne 'say $_ if /A/ ff /C/;'
AB
CD

与 Raku 类似 sed 的fff运算符相比:

~$ echo 'AB\nCD\nEF' | raku -ne 'say $_ if /A/ fff /B/;'
AB
CD
EF
~$ echo 'AB\nCD\nEF' | raku -ne 'say $_ if /A/ fff /C/;'
AB
CD

https://docs.raku.org/routine/fff
https://docs.raku.org/routine/ff
https://raku.org

答案4

TXR Lisp 的awk宏直接支持这个;这rng (范围)运算符有九种变体,用于以各种方式从范围的开头或结尾排除记录:

$ txr -e '(awk ((rng- #/Word A/ #/Word D/)))' data
Word A
Word B
Word C
Word A
Word H
Word I
Word A
Word K
Word A

此外,与 Awk 的范围运算符不同,它与其他运算符结合使用。例如,假设您想打印同时在footobar范围内的记录,starttoend范围中,无论这些范围在数据中如何重叠:

(awk ((and (rng #/foo/ #/bar/)
           (rng #/start/ #/end/))))

相关内容