How can I use a bash script to run nmap and capture both IP and hostname?

11,271

Nmap's normal output is not suited to parsing since it varies from version to version and does not use consistent delimiters or field widths. A better approach would be to use the XML or the Grepable output. The fastest and simplest for what you want would be to choose the Grepable output with -oG and send the output to STDOUT to be processed with awk:

nmap -sn 192.168.0.0/24 -oG - | awk '$4=="Status:" && $5=="Up" {print $2, $3}'

Note that this command uses the new (since Nmap 5.10BETA1 in November 2009) -sn option instead of the old (but still supported) -sP to mean "only do host discovery." Also, I removed the -n option, since you are interested in hostnames. Without doing reverse name resolution, you won't be able to get the output you want.

Because of the way name resolution works (and the multiple sources Nmap can use for name information), there may be more than one hostname for a particular IP address. The Grepable output is deprecated because it cannot convey all the information (such as multiple hostnames, NSE script output, traceroute info, etc) that Nmap produces. If you want a more complete solution, you should use the XML output. Here's an example using xmlstarlet to parse the XML output:

nmap -sn 192.168.0.0/24 -oX - | xmlstarlet sel -t -m "//host/status[@state='up']/.." -v "address[@addrtype='ipv4']/@addr" -o " " -v "hostnames/hostname/@name" -n

Or to print a line for each hostname (including IP addresses with multiple hostnames):

xmlstarlet sel -t -m "//host/status[@state='up']/../hostnames/hostname" -v "../../address[@addrtype='ipv4']/@addr" -o " " -v "@name" -n
Share:
11,271

Related videos on Youtube

developer__c
Author by

developer__c

Updated on September 18, 2022

Comments

  • developer__c
    developer__c over 1 year

    I want to scan my network; and return an output like this:

    Network Scan for 192.168.0.*

    192.168.0.1 computer1

    192.168.0.2 computer2

    192.168.0.3 computer5

    echo Network Scan
    nmap -sP -n <network> | awk '{print  $5}NF == 6{print $6}'
    

    How can I modify the code I already have to include just the IP and hostname?