我正在寻找/搜索一种方法,使 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
- 结尾:
^|_