I apologize in advance as this is a simple question.

So I'm attempting to scan a Class C to identify all mail servers by IP. The vast majority of IPs aren't mail servers. I'm trying to filter out the ones that are.

I've tried the following but they haven't returned what I wanted.

nmap -p 25 | grep report && grep open 


nmap -p (grep report | grep open)

Is there a different utility that I should use? Or is it a problem with my syntax?


It's not clear for me, are you need strings containing only report or open? If so, use: grep :

nmap | grep -E "report|open"

sed :

nmap | sed '/report\|open/!d'

if report and open together

grep :

nmap | grep report | grep open

sed :

nmap | sed '/report.*open\|open.*report/!d'
| improve this answer | |
  • With actual regex! +1 – Tim Jun 7 '12 at 13:01

Rather than post-processing with grep, try passing the --open option to Nmap. This will hide all closed or filtered ports. You can use the -oG or -oA options to output "grepable" results, too. Here's an example that does what I think you're looking for:

nmap -p 25 --open -oA smtp-servers-%y%m%d

The results would be in smtp-servers-20120607.nmap, smtp-servers-20120607.gnmap, and smtp-servers-20120607.xml. You can get IP addresses for open SMTP servers like so:

awk '/\<25/open/tcp/ {print $2}' smtp-servers-*.gnmap

If you really need this all in one pipeline, you could do it like so:

nmap -p 25 --open -oG - | awk '/\<25/open/tcp/ {print $2}'
| improve this answer | |

You need a pipe to both grep invocations:

nmap ... | grep report | grep open

Or, since you tagged with awk, just informatively:

nmap ... | awk '/report/ && /open/'

And sed:

nmap ... | sed '/report/!d;/open/!d'
| improve this answer | |
  • Your sed variant will fail. it will delete both report and open strings, obviously because open doesn't much report and vice versa. Also grep | grep and grep -e -e are not similar. First one will match only strings containing report and open, second one will much either only report either only open either both together. – rush Jun 7 '12 at 12:34
  • All the results of the grep statements are still kicking back IP addresses that do not have port 25 open. Ideally I'd like the statement only to display IPs with open port 25 nothing else. But your suggestions are a lot closer to my intent. Thanks! – John Smith Jun 7 '12 at 12:42
  • @rush you're right about grep -e -e, but for sed, as I understand, OP wants both report and open on the line, the sed will do that properly. – Kevin Jun 7 '12 at 13:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.