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

Network Scan for 192.168.0.* computer1 computer2 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?

1 Answer 1


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 -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 -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

You must log in to answer this question.

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