0

I'm looking/searching for a way to make grep stop when finding the "|_" specific string after having found the search string.

for example, i want to print ONLY the lines starting 2 lines above "address-info:" and stopping at line "|_" AND NOT print "irrelevant lines in between" which BTW could by anything

INPUT:

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

OUTPUT:

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

I'v read man grep and found -A -B -C options, it's OK for -B as I know in advance how many line before but for -A I gave an arbituray high value ie: 99999 in

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

and piping in awk to find "|_"

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

whole line:

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

this in unacceptable in production mode as is it not universal (NOT working in (very unlikly, but possible) cases where the number of lines "address-info:" AND "|_" is more than 99999), CPU/MEM unefficiant and untidy.

I'd like to have a way WITHIN the grep command to acheive this,

any ideas ?

1
  • 2
    Have you considered using the "grep friendly" mode of nmap? For example nmap -oG - Apr 14, 2019 at 13:56

2 Answers 2

1

Use awk directly with a range:

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

grep does not have any 'range' capabilities. But you can pipe the output of grep address-info: -B2 -A 99999 to it.

1
  • OK, all 3 work, thx Apr 18, 2019 at 0:30
0

Use grep to match the start of the lines you want (test if that doesn't match the other lines):

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

Or sed and range pattern (similar to the awk solution)

sed -n '/^Nmap scan report for/,/^|_/p' INPUT.txt
  • begin: ^Nmap scan report for
  • end: ^|_
1
  • OK, all 3 work, thx Apr 18, 2019 at 0:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .