grep STOP 正则表达式替换 -A 选项

grep STOP 正则表达式替换 -A 选项

我正在寻找/搜索一种方法,使 grep 在找到搜索字符串后找到“|_”特定字符串时停止。

例如,我只想打印从“address-info:”上方两行开始并在“|_”行停止的行,而不打印“之间不相关的行”,顺便说一句,这可以通过任何方式打印

输入:

Nmap scan report for ::1.2.3.4
Host script results:
| address-info:
|   IPv4-compatible:
|_    IPv4 address: 1.2.3.4
...
irrelevant lines in between
irrelevant lines in between
irrelevant lines in between
...
Nmap scan report for ::ffff:1.2.3.4
Host script results:
| address-info:
|   IPv4-mapped:
|_    IPv4 address: 1.2.3.4
...
irrelevant lines in between
irrelevant lines in between
irrelevant lines in between
...
Nmap scan report for 2001:0:506:708:282a:3d75:fefd:fcfb
Host script results:
| address-info:
|   Teredo:
|     Server IPv4 address: 5.6.7.8
|     Client IPv4 address: 1.2.3.4
|_    UDP port: 49802

输出:

Nmap scan report for ::1.2.3.4
Host script results:
| address-info:
|   IPv4-compatible:
|_    IPv4 address: 1.2.3.4
Nmap scan report for ::ffff:1.2.3.4
Host script results:
| address-info:
|   IPv4-mapped:
|_    IPv4 address: 1.2.3.4
Nmap scan report for 2001:0:506:708:282a:3d75:fefd:fcfb
Host script results:
| address-info:
|   Teredo:
|     Server IPv4 address: 5.6.7.8
|     Client IPv4 address: 1.2.3.4
|_    UDP port: 49802

我读过 man grep 并找到了 -A -B -C 选项,对于 -B 来说没问题,因为我事先知道之前有多少行,但是对于 -A 我给出了一个任意高值,即: 99999

grep -A99999 -B2 address-info: INPUT.txt

并在 awk 中通过管道查找“|_”

awk 'BEGIN {PAT=1} PAT == 1 {print $0} $1 ~ /^|_/ {PAT=0}

全线:

grep -A99999 -B2 address-info: INPUT.txt | awk 'BEGIN {PAT=1} PAT == 1 {print $0} $1 ~ /^|_/ {PAT=0}'

这在生产模式中是不可接受的,因为它不通用(在“地址信息:”和“|_”行数超过 99999 的情况下(非常不可能,但可能)工作),CPU/MEM 效率低下,襶。

我想在 grep 命令中找到一种方法来实现这一点,

有任何想法吗 ?

答案1

awk直接与范围一起使用:

awk '/^Nmap scan report/;/^Host script results/,/\|_/' INPUT.txt

grep没有任何“范围”功能。但您可以通过管道grep address-info: -B2 -A 99999将其输出。

答案2

用于grep匹配所需行的开头(测试是否与其他行不匹配):

grep -E '^(Nmap scan report for|Host script results:|\|[ _])' INPUT.txt

sed和范围模式(类似于awk解决方案

sed -n '/^Nmap scan report for/,/^|_/p' INPUT.txt
  • 开始:^Nmap scan report for
  • 结尾:^|_

相关内容