Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting by number of repetitions

Tags:

shell

awk

perl

I have a file that looks like this:

192.168.2.2 150.25.45.7 8080
192.168.12.25 178.25.45.7 50
192.168.2.2 142.55.45.18 369
192.168.489.2 122.25.35.7 8080
192.168.489.2 90.254.45.7 80
192.168.2.2 142.55.45.18 457

I made up all the numbers.

I need to sort all these files according to the number of repetitions of the first ip. So the output would ideally look like this:

192.168.2.2 8080 369 457 3
192.168.489.2 8080 80 2
192.168.12.25 50 1

So: first ip, all the ports that were in lines with that first ip, and the number of repetitions.

I've been trying to play with the sort command and awk but I don't want to do extra work and maybe be missing out on some other straightforward solution.

Any idea? Thanks :)

like image 809
coconut Avatar asked Dec 27 '22 09:12

coconut


2 Answers

A Perlish answer would look something like this.

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

my %data;

# Store IP address and port number
while (<DATA>) {
  chomp;
  my ($ip, undef, $port) = split;
  push @{$data{$ip}}, $port;
}

# Sort (in reverse) by length of list of ports
for (sort { @{$data{$b}} <=> @{$data{$a}} } keys %data) {
  say "$_ @{$data{$_}} ", scalar @{$data{$_}};
}

__DATA__
192.168.2.2 150.25.45.7 8080
192.168.12.25 178.25.45.7 50
192.168.2.2 142.55.45.18 369
192.168.489.2 122.25.35.7 8080
192.168.489.2 90.254.45.7 80
192.168.2.2 142.55.45.18 457

Output:

192.168.2.2 8080 369 457 3
192.168.489.2 8080 80 2
192.168.12.25 50 1
like image 141
Dave Cross Avatar answered Dec 31 '22 13:12

Dave Cross


A Perl way:

#!/usr/bin/perl
use strict;
use warnings;

my %repeat;
while(<DATA>) {
    if (/^(\d+(?:.\d+){3})\s\S+\s(\d+)$/) {
        push @{$repeat{$1}}, $2;
    }
}
foreach (sort {@{$repeat{$b}}<=>@{$repeat{$a}}} keys %repeat) {
    my $num = @{$repeat{$_}};
    print "$_ @{$repeat{$_}} $num\n";
}

__DATA__
192.168.2.2 150.25.45.7 8080
192.168.12.25 178.25.45.7 50
192.168.2.2 142.55.45.18 369
192.168.489.2 122.25.35.7 8080
192.168.489.2 90.254.45.7 80
192.168.2.2 142.55.45.18 457

output:

192.168.2.2 8080 369 457 3
192.168.489.2 8080 80 2
192.168.12.25 50 1
like image 23
Toto Avatar answered Dec 31 '22 13:12

Toto