I was tasked with running a NMap scan against our corporate network and compiling a list of only live endpoints. My issue is how to go about separating out the hosts via their open ports (printer/endpoint). For example I want to remove all printers/hosts from the nmap output (-oN) file Corp.txt if port 9100 (printer) is open. The list must also maintain the host name/IP in relation to it's port numbers and open status.

Below is an example of the command I'm running and its output:

nmap -p 80,135,9100 -oN ~/Documents/Corp.txt

Nmap scan report for itbrn1745.domain.net (
Host is up (0.91s latency).
80/tcp   closed http
135/tcp  open   msrpc
9100/tcp closed jetdirect

Nmap scan report for itPC.domain.net (
Host is up (0.0033s latency).
80/tcp   open     http
135/tcp  open     msrpc
9100/tcp filtered jetdirect

Nmap scan report for ap4403.a740 (
Host is up (0.0046s latency).
80/tcp   open     http
135/tcp  filtered msrpc
9100/tcp open     jetdirect

Any advice into the logic of compiling a list of only live endpoints on the network is greatly appreciated.

  • Just use the --open --script reverse-index NSE flags and script from your nmap command-line
    – atdre
    Jun 7, 2016 at 21:19

2 Answers 2


Nmap has alternative output formats for exactly this reason. The Normal output (-oN) that you show is for human-readability only, and shouldn't be processed with scripts, since it is subject to undefined change from version to version.

Most fully-featured Nmap output viewers (like Zenmap or ScanHub) use the XML output format (-oX), which is the machine-readable format that contains the full results of the scan, including advanced features like NSE scripts and traceroute. If you intend to use these features or expand your scanning and reporting beyond simple "all hosts with this port" queries, using one of these output viewers or writing your own that uses XML are your best options. There are libraries for parsing Nmap's XML for most common programming languages.

For simple queries like this one, you can also use Nmap's Grepable output format (-oG). This puts all the port scan data for a host on one line along with the IP and hostname like so:

Host: (ap4403.a740)    Ports: 80/open/tcp//http///, 9100/open/tcp//jetdirect///

In this case, you could just grep -v ' 9100/open' to remove those lines.

When scanning, I prefer to use the "all outputs" option (-oA) to save Normal, XML, and Grepable output to the same filename (with .nmap, .xml, and .gnmap extensions, respectively). That way I have all the output formats in case I need to do post-processing or want to quickly do a visual scan through the output.


As @bonsaiviking mentioned, Nmap supports multiple output formats and there's a number of third-party tools that can help you work with that data. If you want to simply parse the data at the command-line for a simple fire-and-forget solution, a shell script using the -oG option is probably the simplest way.

To give you an idea, here's a quickie I came up with in PowerShell for your scenario. (Based on the file path in your example, it seems you're using Linux - not my forte - but the general concept is fairly portable so long as you understand your operating environment and available tools.)

nmap -p 80,135,9100 -oG - | Where-Object -FilterScript {$_.Contains('Ports:') -and !($_.Contains('9100/open/tcp/'))} | Out-File "$env:UserProfile\Documents\Corp.txt"

Note: The above is not thoroughly tested. You should perform your own sample runs and verification to be certain the output includes all desired data before relying upon it.

The script above is fairly simple.

  • The nmap portion is exactly the same as your original, with one change. The output format was changed from -oN to -oG and the output target was changed to - so that the greppable output gets sent to the console (where we later redirect it through the pipeline) instead of to a file.
  • Where-Object allows us to filter an array of objects based on whatever criteria we want. In this case, we're using it against the greppable output from Nmap, which PowerShell stores as an array of strings. The -FilterScript option allows us to define a PowerShell script (which should output $true or $false, or an equivalent value) to decide what gets filtered (only items resolving to $true will be included in output). This filter script is written to only return port listings, and only for hosts that do not have an open port on TCP 9100.
  • Out-File lets us take the PowerShell output and dump it in a file. Here, $env:UserProfile is used to target the current user's profile folder, and the rest specifies "Corp.txt" in the user's "My Documents" area.

You must log in to answer this question.

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