Extracting specific pattern from nmap

2019-07-27 22:35发布

Imagine I have nmap results like so:

# Nmap 6.40 scan initiated Sat Jun 14 10:14:35 2014 as: nmap ...
Nmap scan report for x.x.x.x.
Host is up (0.21s latency).
PORT   STATE SERVICE
23/tcp open  telnet
| telnet-brute: 
|_  No accounts found

Nmap scan report for y.y.y.y
Host is up (0.24s latency).
PORT   STATE SERVICE
23/tcp open  telnet

Nmap scan report for z.z.z.z
Host is up (0.22s latency).
PORT   STATE SERVICE
23/tcp open  telnet
|_telnet-brute: var1 - <blank>

Nmap scan report for w.w.w.w
Host is up (0.36s latency).
PORT   STATE SERVICE
23/tcp open  telnet
|_telnet-brute: var2 - var3

Nmap scan report for h.h.h.h
Host is up (0.22s latency).
PORT   STATE SERVICE
23/tcp open  telnet
| telnet-brute: 
|_  No accounts found

Nmap scan report for f.f.f.f
Host is up (0.22s latency).
PORT   STATE SERVICE
23/tcp open  telnet
|_telnet-brute: var4 - <blank>

Nmap scan report for b.b.b.b
Host is up (0.23s latency).
PORT   STATE SERVICE
23/tcp open  telnet
| telnet-brute: 
|_  No accounts found


    .
    .
    .

Nmap scan report for a.a.a.a
Host is up (0.22s latency).
PORT   STATE SERVICE
23/tcp open  telnet

# Nmap done at Sun Jun 15 10:20:45 2014 -- 262144 IP addresses (91295 hosts up) scanned in 86769.85 seconds

How can I have the result like:

z.z.z.z  var1  
w.w.w.w  var2  var3
f.f.f.f  var4

I want if there were doesn't show it. (Better to use sed)

UPDATE

What I tries is:

sed -nr '/^Nmap.* /{s///;h};/|_telnet-brute/{n;H;g;s/\n\|\s*/ /;/:/p}' file

Thank you

标签: bash awk sed grep cut
3条回答
太酷不给撩
2楼-- · 2019-07-27 23:05

And the one through grep with Perl-regex option,

$ grep -oP "\w\.\w\.\w\.\w|(?<=brute:).*" file | paste - -
x.x.x.x  var1 - <blank>
y.y.y.y  var2 - var3
z.z.z.z  

Update:

$ awk -v RS="" '{print $5,$18,$20}' file | awk '$2~/var/ {print}'
z.z.z.z var1 <blank>
w.w.w.w var2 var3
f.f.f.f var4 <blank>

If you again want to remove <blank> dtring then run,

$ awk -v RS="" '{print $5,$18,$20}' file | awk '$2~/var/ {gsub (/<blank>/,""); print}'
z.z.z.z var1 
w.w.w.w var2 var3
f.f.f.f var4 

OR

You could do this ina single awk command,

$ awk -v RS="" '$18~/var/ {gsub (/<blank>/,""); print $5,$18,$20}' file
z.z.z.z var1 
w.w.w.w var2 var3
f.f.f.f var4 
查看更多
Animai°情兽
3楼-- · 2019-07-27 23:19

Your data is not consistent (you have |_telnet and | telnet), but this may give you some:

nmap ..... | awk -v RS="" '{print $5,$18,$20}'

But as other say, tweak your output before more processing.

查看更多
爱情/是我丢掉的垃圾
4楼-- · 2019-07-27 23:25

I would do this in Perl:

$ perl -lne '/for (.+)/; $i=$1; (@f = /var./g) && print "$i @f"' file 
z.z.z.z var1
w.w.w.w var2 var3
f.f.f.f var4

Explanation

  • perl -lne : the -ne means "read the input file line by line" (-n) "and apply the script given as -e". The -l adds a newline to each print call (and removes trailing newlines).
  • /for (.+)/; $i=$1; : match the word for followed by a space and capture (that's what the parentheses do) everything to the end of the line. The captured pattern ($1) is saved as $i.
  • @f = /var./g : save all occurrences of var and one more character in the array @f. If you can have >1 characters following var, change that to @f = /var\w*/g.
  • && print "$i @f" : if the previous match was successful, print $i (the IP) and the contents of @f.
查看更多
登录 后发表回答