Count no of netstat states

netstat | awk  '/server/ {for(i=1;i<2;i++) {getline;print}' 
 
Output:
ESTABLISHED
ESTABLISHED
ESTABLISHED
ESTABLISHED
ESTABLISHED
TIME_WAIT
TIME_WAIT
 

From the above command I'm getting all the states. I want to count the states and write to a file, like
"Count of ESTABLISHED is: 5"
"Count of TIME_WAIT is : 2"

How to count in awk, other than passing the output to grep and using -c option.

Looks like you managed to print just the state of each server.
Now, try to push each state as the key in an associative array and keep incrementing the value each time you find the same state in the array keys.

1 Like

Here is my own little concoction I use for such things.
Produces output like:

=====================================
host                    total   FIN_WAIT2 ESTABLISHED
192.168.1.115   |           1           0           1
192.168.1.32    |           1           0           1
86.8.240.6      |           7           6           1
total           |           9           6           3


#!/usr//bin/perl 

use strict;
my ($Proto, $Recv, $Send, $Local, $Foreign, $State);
my ($local, $foreign, $f_port, $l_port);
my $db = {};
my @STATES;
my $stats = {};
our $verbose = 1;


open NETSTAT,  "netstat -nt |" or die "netstat:$!\n"; 

my $headers = my $h = 2;
<NETSTAT> while ($h--);

LOOP:
while (<NETSTAT>) {

    ($Proto, $Recv, $Send, $Local, $Foreign, $State) = split;

    foreach my $grep (@ARGV) {
        next LOOP unless /$grep/;
    }

    print if $verbose ;

    ($foreign, $f_port) = split ':', $Foreign;
    ($local, $l_port) = split ':', $Local;

    $stats->{$State}++;

    $db->{$foreign}->{connections}++ ;
    $db->{$foreign}->{states}->{$State}++;
    $db->{total}->{connections}++ ;
    $db->{total}->{states}->{$State}++;
}

@STATES = (keys %$stats);
printf "=====================================\n";
printf "%-16s %12s", "host", "total";
map { printf "%12s", $_ } @STATES;
print "\n";

foreach my $h (sort keys %$db) {
    printf "%-16s|", $h;
    printf "%12d",  $db->{$h}->{connections};
    foreach my $s (@STATES) {
        my $state = $db->{$h}->{states}->{$s} +  0; 
        printf "%12d",  $state;
    }
    print "\n";

}

1 Like
netstat -antu | awk '/LISTEN|ESTABLISHED|TIME_WAIT/{a[$6]++}; END { for(b in a) print "Count of "b" is: "a}'

Hi in2nix4life,

Thanks for your reply,

-antu option is not working in ksh.

I used

netstat -a

which gave me the below output.

tcp 0 0 server1.00000 server2.00000 ESTABLISHED

from that I used ur suggestion which produced the below o/p:

netstat -a | grep server1 |  awk '/LISTEN|ESTABLISHED|TIME_WAIT/{a[$6]++}; END { for(b in a) print "Count of "b" is: "a}' 
 
Count of LISTEN is:2
Count of ESTABLISHED is: 18
Count of TIME_WAIT is: 5

Thanks

You can merge the grep behavior into the awk code and get rid of the invocation of grep :

netstat -a | awk '/server/ && /LISTEN|ESTABLISHED|TIME_WAIT/{a[$6]++}; END { for(b in a) print "Count of "b" is: "a}' 

Thanks Don Cragun.