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 ?

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

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.

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: ^|_

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.