Reputation: 65
This is an awk related question (no perl/cut/sed... please :) ).
What I'm actually trying to do is to get the destination address from netstat output on MacOS using only awk.
Here an example of the output:
$ netstat -nl -p tcp
Active Internet connections
Proto Recv-Q Send-Q Local Address Foreign Address (state)
tcp4 0 0 127.0.0.1.26164 127.0.0.1.50100 ESTABLISHED
tcp4 0 0 127.0.0.1.50100 127.0.0.1.26164 ESTABLISHED
If I run the awk parser, I get :
$ netstat -nl -p tcp | awk '/tcp/ {split($5,a,".") ; for(i=1; i<NF-1; i++) printf a[i] "."; printf "\n"}'
127.0.0.1.
127.0.0.1.
1) Is there a way to remove the "." at the end of the IP address?
2) Is there a better "awk" way to obtain the same result?
PS: I know you can type something like
$ netstat -nl -p tcp | perl -ape '$_=$F[4];s/((?:\d+\.){3}\d+)\D.*/$1\n/'
to get the correct result ;)
Thanks!
Upvotes: 1
Views: 662
Reputation: 3380
Why not do it the UNIX way? Pipe it to another utility:
netstat -nl -p tcp | awk '/tcp/{print $4}' | sed 's/\.[0-9]*$//'
Or, to do the whole thing in awk
, use sub()
to delete the last part of the IP:
netstat -nl -p tcp | awk '/tcp/{sub(/\.[0-9]*$/,"",$4); print $4}'
Unfortunately, BSD grep
(which is what OSX has) does not have the -P
option, else you could do:
netstat -nl -p tcp | awk '/tcp/{print $4}' | grep -oP '.*(?=\.\d+)'
Upvotes: 1
Reputation:
I think this is the easiest and most general way to do this using awk
awk '{match($5,/(.*)\./,x);print x[1]}' file
Upvotes: 1
Reputation: 207798
I think I prefer this approach with multiple alternative FS
- either dot or space:
netstat -nl -p tcp |awk -F'[. ]*' '/tcp/{print $9,$10,$11,$12}' OFS="."
Upvotes: 1
Reputation: 2612
The other reply is probably better but here's my attempt:
netstat -nl -p tcp | awk '/tcp/{split($5,a,".");for(x in a)if(a[x+1]""){y=y SEP a[x]; SEP="."}print y;y="";SEP=""}'
Explanation
if(a[x+1]"")
checks if there is a next element in an array (i.e. if it's not processing the last element - the port) and the ""
converts the number into a string by applying concatenation so 0
doesn't evaluate to False
SEP
variable just makes sure the output won't start with a .
, and gets reset at the end.Upvotes: 1
Reputation: 290235
Just play with the number of elements coming from split()
:
awk '/tcp/ {n=split($5,a,".")
^-----------------------------------------------------------\
for(i=1; i<n; i++) printf "%s%s", a[i], (i==n-1?"\n":".") |
^-----------------------------^^^^^^-------------/
}'
n=split($5,a,".")
split as you were doing, but storing in the variable n
the amount of fields that this produces.for(i=1; i<n; i++) printf "%s%s", a[i], (i==n-1?"\n":".")}
loop through these values, printing either a dot .
or a new line depending on the loop time.$ netstat ... | awk '/tcp/ {n=split($5,a,"."); for(i=1; i<n; i++) printf "%s%s", a[i], (i==n-1?"\n":".")}'
127.0.0.1
127.0.0.1
Upvotes: 1