Michael A
Michael A

Reputation: 9900

Using AWK to print values from two different field seperators?

I have the following (somewhat trimmed) logs file from nmap:

Host: 111.111.111.5 ()  Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows XP microsoft-ds/
Host: 111.111.111.10 () Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows Server 2003 3790 Service Pack 2 microsoft-ds/
Host: 111.111.111.31 () Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows Server 2003 3790 Service Pack 1 microsoft-ds/
Host: 111.111.111.73 () Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows 7 Professional 7601 Service Pack 1 microsoft-ds/
Host: 111.111.111.128 ()    Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows 2000 microsoft-ds/
Host: 111.111.111.145 ()    Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows Server (R) 2008 Standard 6001 Service Pack 1 microsoft-ds/
Host: 111.111.111.202 ()    Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows 2000 microsoft-ds/
Host: 111.111.111.218 ()    Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows 7 Professional 7601 Service Pack 1 microsoft-ds/
Host: 111.111.111.220 ()    Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows Server 2008 R2 Standard 7601 Service Pack 1 microsoft-ds/
Host: 111.111.111.221 ()    Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows Server (R) 2008 Standard 6001 Service Pack 1 microsoft-ds/
Host: 111.111.111.223 ()    Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows Server (R) 2008 Standard 6001 Service Pack 1 microsoft-ds/
Host: 111.111.111.227 ()    Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows 2000 microsoft-ds/
Host: 111.111.111.229 ()    Ports: 139/open/tcp//netbios-ssn//Windows Server 2003 3790 Service Pack 1 netbios-ssn/, 445/filtered/tcp//microsoft-ds///
Host: 111.111.111.230 ()    Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows 7 Ultimate N 7600 microsoft-ds/

I'm trying to use awk to print out the ip, followed by the machine type. An example output would look like the following:

111.111.111.5 Windows XP

Using AWK I've extracted the ip address and some of the information:

cat smb-sweep-oG.txt  | awk '/Windows/ {print $2 " " $6}' 

However I need to use a different field separator to extract the operating system information I believe? Is there a way to approach this without creating a python script dedicated to the task?

Upvotes: 0

Views: 90

Answers (3)

James Brown
James Brown

Reputation: 37404

An alternative in awk. Remove the last field ($NF), printf last part of $6 (=Windows) and everything after that. No need to fiddle with the FS:

$ awk '
{
    NF--; $0=$0                            # remove last field
    n=split($6,a,"/")                      # split $6 by /s
    printf "%s %s ", $2,a[n]               # output last a[]
    for(i=7; i<=NF; i++)                   # iterate the rest of fields
        printf "%s%s", $i, (i<NF?OFS:ORS)  # output
}' foo
111.111.111.5 Windows XP
111.111.111.10 Windows Server 2003 3790 Service Pack 2
111.111.111.31 Windows Server 2003 3790 Service Pack 1

Upvotes: 1

Arjun Mathew Dan
Arjun Mathew Dan

Reputation: 5298

Something like this:

awk -F\/ '{sub(/^[^ ]+ /,"",$1); sub(/ .*/,"", $1); sub(/ [^ ]*$/,"",$(NF-1)); print $1, $(NF-1)}' File

111.111.111.5 Windows XP
111.111.111.10 Windows Server 2003 3790 Service Pack 2
111.111.111.31 Windows Server 2003 3790 Service Pack 1
111.111.111.73 Windows 7 Professional 7601 Service Pack 1
111.111.111.128 Windows 2000
111.111.111.145 Windows Server (R) 2008 Standard 6001 Service Pack 1
111.111.111.202 Windows 2000
111.111.111.218 Windows 7 Professional 7601 Service Pack 1
111.111.111.220 Windows Server 2008 R2 Standard 7601 Service Pack 1
111.111.111.221 Windows Server (R) 2008 Standard 6001 Service Pack 1
111.111.111.223 Windows Server (R) 2008 Standard 6001 Service Pack 1
111.111.111.227 Windows 2000
111.111.111.229
111.111.111.230 Windows 7 Ultimate N 7600

In the second last line.. the server name is appearing at a different location and hence not printed in the output. So, in case the server name could appear in either of the two locations, then you could go for:

awk -F\/ '{sub(/^[^ ]+ /,"",$1); sub(/ .*/,"",$1); sub(/ [^ ]*$/,"",$(NF-1)); sub(/ [^ ]*$/,"",$7); print $1, $(NF-1), $7}' File

111.111.111.5 Windows XP
111.111.111.10 Windows Server 2003 3790 Service Pack 2
111.111.111.31 Windows Server 2003 3790 Service Pack 1
111.111.111.73 Windows 7 Professional 7601 Service Pack 1
111.111.111.128 Windows 2000
111.111.111.145 Windows Server (R) 2008 Standard 6001 Service Pack 1
111.111.111.202 Windows 2000
111.111.111.218 Windows 7 Professional 7601 Service Pack 1
111.111.111.220 Windows Server 2008 R2 Standard 7601 Service Pack 1
111.111.111.221 Windows Server (R) 2008 Standard 6001 Service Pack 1
111.111.111.223 Windows Server (R) 2008 Standard 6001 Service Pack 1
111.111.111.227 Windows 2000
111.111.111.229  Windows Server 2003 3790 Service Pack 1
111.111.111.230 Windows 7 Ultimate N 7600

If you want to filter out only Windows sections:

 awk -F\/ '/Windows/ {sub(/^[^ ]+ /,"",$1); sub(/ .*/,"",$1); sub(/ [^ ]*$/,"",$(NF-1)); sub(/ [^ ]*$/,"",$7); print $1, $(NF-1), $7}' File

Upvotes: 3

George Vasiliou
George Vasiliou

Reputation: 6335

As an alternative that will work with all your lines , since the system info you want to print is always the last field ($NF):

$ a="Host: 111.111.111.230 ()    Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows 7 Ultimate N 7600 microsoft-ds/"
$ awk -F'/' '{split($1,f," ");print f[2],$(NF-1)}' <<<"$a"
#output
111.111.111.230 Windows 7 Ultimate N 7600 microsoft-ds

By the way, you could use multiple delimiters in GNU awk like this:

$ a="Host: 111.111.111.5 ()  Ports: 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds//Windows XP microsoft-ds/"
$ awk -F"[ //]" '{print $2,$20,$21,$22}' <<<"$a"  #delimiter is space and //
#output:
111.111.111.5 Windows XP microsoft-ds

But in your file the second method will not work OK because document structure is not the same in all lines.

Upvotes: 2

Related Questions