Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Say I want to know how many unique clients are connected to port 5222 on a server.

Can you find a way better/faster/stronger than this?

netstat -nt | grep ':5222.*ESTABLISHED' | awk '{ print $5 }' \
| grep -Po '[0-9]{1,3}(\.[0-9]{1,3}){3}' | uniq | wc -l

I know this is a too simple regex for a internet address, but seems unecessary to check for well formed addresses, as netstat will probably output only valid ones.

Can someone come to a netstat -nt | awk { awesomeness }?

A netstat -nt | awk { simplicity }| uniq | wc -l, maybe?

share|improve this question
    
Trying to make this one liner a bit shorter doesn't seem like a useful task to me. Perhaps codegolf would be a better venue for this question. –  Kyle Jones Apr 10 '12 at 20:19

3 Answers 3

up vote 2 down vote accepted

If you are on Linux and can handle having ss installed:

ss -o state established '( dport = :5222 )'|awk -F"[\t :]+" 'NR!=1{ ip[$5]+=1 } END{ for (i in ip){n++};print n }'

If you would like the awk explained just let me know.

share|improve this answer
    
Great awk {awesomeness} indeed! –  motobói Apr 11 '12 at 19:16
    
I think I understood the logic of this, but why use NR block to populate the hash? –  motobói Apr 11 '12 at 19:37
    
And thank you very much for introduce me to ss! –  motobói Apr 11 '12 at 20:02
    
NR doesn't populate the hash, we just use it to skip the headers. For the first line, NR will equal 1, then the next line it will equal 2, and so on. It stores the ip as an index value in the ip[] array. –  JodieC Apr 11 '12 at 23:30

Set proper field separator, then use awk built-in regex matching to get rid of greps. Here is the version with piping output to uniq. IMO, there is no real need for completely replacing uniq with some awk code, because it gets less simple and less unix-y.

netstat -nt  | gawk --re-interval -F':|[ ]+' '$7==5222 && $8=="ESTABLISHED" && $6 ~ /[0-9]{1,3}(\.[0-9]{1,3}){3}/{print $6}' | uniq

But it isn't a lot more complicated, and it still looks ok as one-liner:

netstat -nt  | gawk --re-interval -F':|[ ]+' '$7==5222 && $8=="ESTABLISHED" && $6 ~ /[0-9]{1,3}(\.[0-9]{1,3}){3}/{a[$6]} END{for (i in a) print i}'
share|improve this answer

Try this:

netstat -nt | awk '/:5222.*ESTABLISHED/ { split ($5, a, ":"); print a[1] }' | uniq | wc -l

It would be possible to do the uniq and wc in awk also, of course, but it would probably be more verbose.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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