Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

How can I generate from this INPUT in "general"

INPUT (/proc/net/ip_conntrack)

udp      17 0 src= dst= sport=29249 dport=39802 packets=3 bytes=408 [UNREPLIED] src= dst= sport=39802 dport=29249 packets=0 bytes=0 mark=0 use=2
udp      17 146 src= dst= sport=56932 dport=43645 packets=924 bytes=406167 src= dst= sport=43645 dport=56932 packets=1042 bytes=546092 [ASSURED] mark=0 use=2
tcp      6 118 SYN_SENT src= dst= sport=2518 dport=47385 packets=2 bytes=104 [UNREPLIED] src= dst= sport=47385 dport=2518 packets=0 bytes=0 mark=0 use=2
udp      17 147 src= dst= sport=56937 dport=43647 packets=924 bytes=406167 src= dst= sport=43647 dport=56937 packets=1042 bytes=546092 [ASSURED] mark=0 use=2
tcp      6 119 SYN_SENT src= dst= sport=2514 dport=47384 packets=2 bytes=104 [UNREPLIED] src= dst= sport=47384 dport=2514 packets=0 bytes=0 mark=0 use=2
udp      17 163 src= dst= sport=67 dport=68 packets=29 bytes=9512 src= dst= sport=68 dport=67 packets=27 bytes=8856 [ASSURED] mark=0 use=2
tcp      6 1 TIME_WAIT src= dst= sport=55479 dport=80 packets=7 bytes=725 src= dst= sport=80 dport=55479 packets=5 bytes=1963 [ASSURED] mark=0 use=2

to this output?


udp   3
tcp   2
udp   1
tcp   1

So that from the INPUT datas the OUTPUT would be 3 columns:

protocoll   src-ip-address  count-connection-numbers

So that the IP with the most number of connections would be at top.

share|improve this question

Using sed, uniq, sort, awk and column:

sed -n -r 's/^(udp|tcp)\s*[^=]*=([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*$/\1 \2/p' infile \
  | sort | uniq -c | sort -nr | awk '{print $2" "$3" "$1'} | column -t > outfile
share|improve this answer

You can use perl one-liner to get it done, it's very easy!

perl -lane 'print "$F[0] $1" if /src=(.*?)\s/' /proc/net/ip_conntrack | sort | uniq -c | sort -rn -k 1
share|improve this answer

There are two steps: extract the protocol and source addresses, and collect and sort. You already know how to do the second, so let's see how to do the first.

You already had a way to extract the source addresses:

sed -ne 's/^.*src=\([^ ]*\).*/\1/p'

That extracts the last src= field though; here we want to extract the first. It's a bit inconvenient in sed, but can be done.

sed -n -e 's/\(src=[^ ]*\).*/\1/' -e 's/^.*src=\([^ ]*\).*/\1/p'

To retain the first field, just apply the last replacement to the part after the first space.

sed -n -e 's/\(src=[^ ]*\).*/\1/' -e 's/ .*src=\([^ ]*\).*/ \1/p'

This is terse and not very clear. Here's an about equally terse, but clearer way to get the same output with awk. Call match to find the extent of the first src= field, then print out the corresponding part of the line.

awk 'match($0, / src=[^ ]*/) {print $1 substr($0, RSTART, RLENGTH)}'

Finally, pipe into the second stage (sort, obtain counts, and sort by count).

awk 'match($0, / src=[^ ]*/) {print $1 substr($0, RSTART, RLENGTH)}' |
sort | uniq -c | sort -nr
share|improve this answer
s/ .*src= makes a greedy grab and returns the 2nd src= ip.. One alternative is 's/ [^=]*= – Peter.O Jun 23 '11 at 19:20
@fred I shouldn't post so late at night, I hadn't even noticed the second src= field. s/ [^=]*=\([^ ]*\)/\1/p would work, but it would rely on src= being the first field with an equal sign, and that feels too inflexible. (P.S. I forget, do you do Perl? You may be interested in this text replacement benchmark.) – Gilles Jun 23 '11 at 20:22
I too hadn't noticed the second src= until after I had +1'd your answer, based on a visual 'test', and then thought I'd better give it a 'real' test... Re. perl: I look on in awe :) – Peter.O Jun 23 '11 at 22:25

Using awk and sort:

/usr/bin/awk -F" " '
  proto = $1
  for(i = 2; i <= NF; ++i) 
    if ($i ~ /^src=/) 
      scrip = $i
      srcip = sub(/^src=/, "", scrip)
      key = proto SUBSEP scrip
  for (var in a)
    split(var, subkey, SUBSEP)
    printf "%-5s %-18s %-8s\n", subkey[1], subkey[2], a[var]
' infile | sort -rn -k3,3
share|improve this answer
Your output prints both instances (per line) of src=... The sample output requires only the first instance... – Peter.O Jun 23 '11 at 19:42
use strict;
use warnings;

my %count;

# extract protocol and source-ip-address, count rows with same values
while(<>) {
  if (/^([^ ]+).*src=([0-9.]+)/) {
    $count{"$1 $2"}++;

# sort by count
for my $p_src (sort {$count{$b} <=> $count{$a}} keys %count) {
  print "$p_src\t$count{$p_src}\n";

Example (your data isn't very interesting)

$ eg.pl eg.txt
tcp        1
tcp       1
tcp       1
udp       1
udp      1
udp 1
udp 1
share|improve this answer
Based on the sample output provided, only the first instance (per line) of src= ip should be printed... – Peter.O Jun 23 '11 at 19:49

Your Answer


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.