4

Want to transform this nmap output:

Nmap scan report for 192.168.1.38
Host is up (0.0092s latency).
MAC Address: B8:78:2E:XX:XX:XX (Apple)
Nmap scan report for 192.168.1.39
Host is up (0.0092s latency).
MAC Address: 40:6C:8F:XX:XX:XX (Apple)
Nmap scan report for 192.168.1.201
Host is up (0.019s latency).
MAC Address: 3C:DF:A9:XX:XX:XX (Arris Group)
Nmap scan report for 192.168.1.36
Host is up.
Nmap done: 256 IP addresses (4 hosts up) scanned in 1.77 seconds

Into:

192.168.1.38 (Apple)
192.168.1.39 (Apple)
192.168.1.201 (Arris Group)

Note that the last IP 192.168.1.36 (scanner IP) is not included.

With: sudo nmap -n -sn 192.168.1.0/24 | awk '/Nmap scan report/{printf $5;printf " ";getline;getline;print $4;}' > scan-output.txt

I include the scanner IP and only the first word of the vendor.

192.168.1.38 (Apple)
192.168.1.39 (Apple)
192.168.1.201 (Arris
192.168.1.36 IP

Please help. Thank you in advance!

Carlos
  • 135
  • 1
  • 1
  • 8

3 Answers3

2
$ awk '/^Nmap scan report for/ {ip = $5}  /^(MAC Address|Nmap done)/ {$1 = $2 = $3 = ""; print ip, $0}'

For a more complete vendor name I blanked out three fields and displayed the rest. Consider trimming parens with tr -d '()'. Consider using END to emit that final address: awk '... END {print ip, "IP"}'

J_H
  • 17,926
  • 4
  • 24
  • 44
  • Modified yours a little bit to add the vendor full name (is not the best way) sudo nmap -n -sn 192.168.1.0/24 | awk '/Nmap scan report for/ {ip = $5} /^MAC/ {print ip, $4, $5, $6, $7, $8, $9, $10}' – Carlos Oct 28 '17 at 01:11
1

awk to help, following may help you in same.

awk '/Nmap scan report for / && ip && vendor{print ip,vendor;ip=vendor=""} /Nmap scan report for /{ip=$NF;next} /MAC Address/{sub(/.*\(/,"(");;vendor=$0;next} END{if(ip){print ip,"IP"}}'  Input_file

EDIT: Adding a non-one liner form of solution with explanation too here.

awk '
/Nmap scan report for / && ip && vendor{ ##Checking condition here if line has string Nmap scan report for &&(conditional operator) value of variable ip is..
                                         ##NOT NULL &&(conditional operator) value of variable named vendor is NOT NULL too, if all conditions met then do following.
  print ip,vendor                        ##Printing the values of variable ip and variable vendor here.
  ip=vendor=""                           ##Nullifying variables ip and vendor here.
}
/Nmap scan report for /{                 ##Checking condition if a line contains string Nmap scan report for, if yes, then do following.
  ip=$NF;                                ##creating variable named ip whose value is the $NF value where $NF represents the value of last field.
  next                                   ##Using next will skip all further statements.
}
/MAC Address/{                           ##Checking condition if a line contains string MAC Address then perform following.
  sub(/.*\(/,"(");                       ##Using sub utility of awk, which will substitute as per your provided regex, so I am substituting everything from starting to
                                         ##till ( with (, so that if a vendor name has spaces in it, it should pick those things too, like your sample Input has.
  vendor=$0;                             ##Now assigning the value of new edited line to variable vendor.
}
END{
  if(ip){                                ##In END block of awk code, checking here if variable ip value is NOT NULL then do following.
    print ip,"IP"                        ##Printing the value of variable ip and string IP here too.
}
}' Input_file                            ##Mentioning the Input_file name here.
RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93
  • 1
    Excellent explanation. But in the test results the last line with 192.168.1.36 IP should not appear (result with no latency due it is the scanner interface). The results should only contain the hosts detected and their OUI. – Carlos Oct 28 '17 at 07:28
  • @Carlos, sorry but in your output it was there? could you please explain more on same. – RavinderSingh13 Oct 28 '17 at 07:30
  • @Carlos, or you don't want any IP which is coming LAST? – RavinderSingh13 Oct 28 '17 at 07:32
  • In my first attempt of the main post I get "192.168.1.36 IP" in the last line that is always the scanner IP (last IP), but I want to exclude it from the results. The difference between scanner IP and scanned host IPs is the latency.With your great explanation I will work on it if you don't put it here first ;-). Thank you! – Carlos Oct 28 '17 at 19:21
  • @Carlos, thanks for encouragement about explanation. how could I differentiate between scanner IP and scanned host IP with latency? If you could explain me I could edit my code accordingly then. – RavinderSingh13 Oct 29 '17 at 03:03
  • Sure! The dafault nmap output contains 3 rows per host, first line with the host IP, second line with the response time (latency) and the third line with its MAC address. But, the last three lines, contains, the scanner IP, "Host is up" text and the scan general results (total hosts online and the time taken from the scan). The lack of "latency" string could be the way to identify the scanner IP that should not be included in the final results (after using awk). The answer from @3161993 works fine, if you want to test it. Thank you in advance. – Carlos Oct 29 '17 at 13:41
1

Using awk

One-liner:

awk '/^(Nmap scan|MAC Address)/{ORS=(f+=sub(/^.*(for|:..) /,""))%2?OFS:RS; print}END{printf "IP\n"}' infile

Better Readable:

awk '/^(Nmap scan|MAC Address)/{
            ORS=(f+=sub(/^.*(for|:..) /,""))%2?OFS:RS;
            print
      }
      END{
           printf "IP\n"
      }
     ' infile

Test Results:

$ cat infile
Nmap scan report for 192.168.1.38
Host is up (0.0092s latency).
MAC Address: B8:78:2E:XX:XX:XX (Apple)
Nmap scan report for 192.168.1.39
Host is up (0.0092s latency).
MAC Address: 40:6C:8F:XX:XX:XX (Apple)
Nmap scan report for 192.168.1.201
Host is up (0.019s latency).
MAC Address: 3C:DF:A9:XX:XX:XX (Arris Group)
Nmap scan report for 192.168.1.36
Host is up.
Nmap done: 256 IP addresses (4 hosts up) scanned in 1.77 seconds

$ awk '/^(Nmap scan|MAC Address)/{ORS=(f+=sub(/^.*(for|:..) /,""))%2?OFS:RS; print}END{printf "IP\n"}' infile
192.168.1.38 (Apple)
192.168.1.39 (Apple)
192.168.1.201 (Arris Group)
192.168.1.36 IP

--edit for comment--

$ awk 'f==2{print s; f=s=""}/^(Nmap scan|MAC Address)/{sub(/^.*(for|:..) /,"");f++;s=(s?s OFS :"")$0}END{if(f==2)print s}' infile
192.168.1.38 (Apple)
192.168.1.39 (Apple)
192.168.1.201 (Arris Group)
Akshay Hegde
  • 16,536
  • 2
  • 22
  • 36
  • In the test results the last line with 192.168.1.36 IP should not appear (result with no latency due it is the scanner interface). – Carlos Oct 28 '17 at 07:25
  • 1
    `awk 'f==2{print s; f=s=""}/^(Nmap scan|MAC Address)/{sub(/^.*(for|:..) /,"");f++;s=(s?s OFS :"")$0}END{if(f==2)print s}' infile` – Akshay Hegde Oct 28 '17 at 07:44