EB-
EB-

Reputation: 67

Nmap output with IP and MAC address in same line

Given the answer to this question,

I would like to know how to obtain from the following 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 done: 256 IP addresses (3 hosts up) 

scanned in 1.77 seconds

The following parse result ouput:

192.168.1.38 B8:78:2E:XX:XX:XX
192.168.1.39 40:6C:8F:XX:XX:XX
192.168.1.201 3C:DF:A9:XX:XX:XX

Thank you.

Upvotes: 1

Views: 5098

Answers (6)

ufopilot
ufopilot

Reputation: 3985

  • if $0 ~ "Nmap scan" ? $NF row contains Nmap scan print last column $NF
  • elseif $0 ~ "MAC Address" ? $3 row contains MAC Address print third column
  • else prinf blank
awk '{printf "%s", ($0 ~ "Nmap scan" ? $NF : ($0 ~ "MAC Address" ? $3 "\n" : " "))}' file
192.168.1.38 B8:78:2E:XX:XX:XX
192.168.1.39 40:6C:8F:XX:XX:XX
192.168.1.201 3C:DF:A9:XX:XX:XX

Upvotes: 0

not2qubit
not2qubit

Reputation: 17037

This is your one-line life-saver, using awk and compatible with Windows EOL.

nmap -sn 192.168.1.1/24 --exclude 192.168.1.36 | awk '1==1 {res=gsub("\r","")}/Nmap scan report for/{gsub(/[()]/,"",$NF); printf "%s\t", $NF;}/MAC Address:/{gsub("[()]","");printf "%s   ", $3; for(i=4; i<=NF; ++i) printf "%s ", $i; printf "\n"}'

The output is:

192.168.1.1     44:48:B9:6A:E0:30   MitraStar Technology
192.168.1.30    A8:96:75:01:AB:F0   Motorola Mobility, a Lenovo Company
192.168.1.39    54:27:1E:E4:29:11   AzureWave Technology
192.168.1.45    B4:E4:54:D0:90:6A   Amazon Technologies
192.168.1.49    C0:D7:AA:89:40:5E   Arcadyan
192.168.1.200   74:EA:E8:DE:56:D7   Arris Group

Now this is kind of unreadable and it took me some time to get this right. So let me explain.

To see the default awk variables, use:

# awk --dump-variables '' && cat awkvars.out

ARGC: 1
ARGIND: 0
ARGV: array, 1 elements
BINMODE: 0
CONVFMT: "%.6g"
ENVIRON: array, 77 elements
ERRNO: ""
FIELDWIDTHS: ""
FILENAME: ""
FNR: 0
FPAT: "[^[:space:]]+"
FS: " "
FUNCTAB: array, 42 elements
IGNORECASE: 0
LINT: 0
NF: 0
NR: 0
OFMT: "%.6g"
OFS: " "
ORS: "\n"
PREC: 53
PROCINFO: array, 60 elements
RLENGTH: 0
ROUNDMODE: "N"
RS: "\n"
RSTART: 0
RT: ""
SUBSEP: "\034"
SYMTAB: array, 28 elements
TEXTDOMAIN: "messages"

Now the important awk variables:

  • $NF = [awk] Number of Fields (of the current record.)

    NF is a built-in variable whose value is the number of fields in the current record, and awk updates the value of NF automatically, each time a record is read. No matter how many fields there are, the last field in a record can be represented by $NF.

  • $NR = [awk] (The) Number of the current record.

  • $FS = [awk] Field Separator (default is a single space: $FS=" ".)

  • $OFS = [awk] Output Field Separator (default is a single space: $ORS=" ".)

  • $RS = [awk] Record Separator (default is a single space: $ORS="\n".)

  • $ORS = [awk] Output Record Separator (default is a single space: $ORS="\n".)

Finally the Explanation:

Let's break up and look at the awk line again. We have:

1==1{res=gsub("\r","")}
/Nmap scan report for/{gsub(/[()]/,"",$NF); printf "%s\t", $NF;}
/MAC Address:/{
    gsub("[()]","");
    printf "%s   ", $3; 
    for(i=4; i<=NF; ++i) printf "%s ", $i; 
    printf "\n"}
  • 1==1{res=gsub("\r","")} - [true] removes all (Win) \r from input.

  • /Nmap scan/{gsub(/[()]/,"",$NF); print $NF} - Remove (via RegEx) all ()'s in the last field ($NF), and then print.

  • (a): /MAC Address:/{for(i=3; i<=NF; ++i) - For all lines starting with "MAC Address:", the MAC address (and Vendor info) is found in the 3 field and onward...

  • (b): printf "%s ", $i; - printf the string in each field...

  • (c): printf "\n"} - At the end of each line, print a newline.

Upvotes: 2

Brad Nicholas
Brad Nicholas

Reputation: 66

Adding to the post above to just get a sorted list with IP, MAC and Manufacturer

sudo nmap -sP 192.168.1.0/24 | awk '/Nmap scan report for/{printf $5;}/MAC Address:/{print " => "$3,$4,$5,$6,$7,$8;}' | sort

Upvotes: 0

Pipo
Pipo

Reputation: 5093

Credits to this post

sudo nmap -sP 172.31.201.0/24 | awk '/Nmap scan report for/{printf $5;}/MAC Address:/{print " => "$3;}' | sort

Upvotes: 0

Akshay Hegde
Akshay Hegde

Reputation: 16997

$ awk '/Nmap scan/{ip=$NF;next}ip && /MAC/{print ip, $3}' infile
192.168.1.38 B8:78:2E:XX:XX:XX
192.168.1.39 40:6C:8F:XX:XX:XX
192.168.1.201 3C:DF:A9:XX:XX:XX

$ awk '/Nmap scan|MAC/{gsub(/\(.*/,"");printf "%s%s", $NF, ++c%2?OFS:RS}' infile
192.168.1.38 B8:78:2E:XX:XX:XX
192.168.1.39 40:6C:8F:XX:XX:XX
192.168.1.201 3C:DF:A9:XX:XX:XX

Input:

$ 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 done: 256 IP addresses (3 hosts up) 

Upvotes: 2

RavinderSingh13
RavinderSingh13

Reputation: 133730

Following awk may help you in same.

awk '
/Nmap scan report/{
  val=$NF;
  next
}
/MAC Address:/{
  sub(/.*Address: /,"");
  sub(/ .*/,"");
  print val,$0
}
'   Input_file

Upvotes: 2

Related Questions