考虑一下我有下面列出的文件。我需要从正则表达式模式的每个实例中选择所有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 的范围运算符不同,它与其他运算符结合使用。例如,假设您想打印同时在foo
tobar
范围内的记录,和在start
toend
范围中,无论这些范围在数据中如何重叠:
(awk ((and (rng #/foo/ #/bar/)
(rng #/start/ #/end/))))