Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello monks

I have a piece of my data below

6 [107.108.109.110] [111.112.113.114] Get 08:35:04.3662; 29459 2 [107.108.109.110] [1.2.3.4] GetNext 08:34:02.3362; 29459 3 [107.108.109.110] [11.12.13.14] GetNext 08:34:04.3462; 29459 7 [11.12.13.14] [107.108.109.110] GetReply 08:34:04.3632; 29459 5 [1.2.3.4] [107.108.109.110] GetReply 08:34:02.3562; 29459 4 [111.112.113.114] [107.108.109.110] GetReply 08:35:04.3752; 29459
I'm using the following sort routine
@array = sort { $a->[5] <=> $b->[5] # || $a->[3] cmp $b->[3] } @array;
What I'm trying to do is match up the IP's (i.e)
6 [107.108.109.110] [111.112.113.114] Get 08:35:04.3662; 29459 4 [111.112.113.114] [107.108.109.110] GetReply 08:35:04.3752; 29459 2 [107.108.109.110] [1.2.3.4] GetNext 08:34:02.3362; 29459 5 [1.2.3.4] [107.108.109.110] GetReply 08:34:02.3562; 29459 3 [107.108.109.110] [11.12.13.14] GetNext 08:34:04.3462; 29459 7 [11.12.13.14] [107.108.109.110] GetReply 08:34:04.3632; 29459
Anyone have any ideas? I'm at a loss.

Thanks

Replies are listed 'Best First'.
Re: Need sorting help
by hawtin (Prior) on Jan 31, 2003 at 22:53 UTC

    The <=> operator does a numeric comparison. The IP addresses are not numbers, you want cmp. Try replacing all <=> with cmp.

    Update: Ah, the benefit of not reading the question before answering it.

    What I should have suggested is that you construct a key for each row based on the data in the row. If you, say append the source and target IP addresses (i.e. make "$src:$target" the key) (remembering to reverse the order when dealing with a reply) then it should all work. You may need to also incorporate some other data, for example, the time to ensure uniqueness?

Re: Need sorting help
by tall_man (Parson) on Feb 01, 2003 at 00:47 UTC
    I agree with hawtin about making a hash with keys based on the source and destination (reversed for replies). But what you need to gather the messages together is a hash of arrays. That will also preserve the sequence within each exchange, since I assume the log is in time order. (It will not preserve the overall sequence, but that could be another sort after you have them grouped). Here is my implementation:
    use strict; my %calls; while (<>) { my $line = $_; my ($num, $source, $dest, $type) = split (/\s+/,$line,5); my $key; if ($type eq "GetReply") { $key = $dest . ":" . $source; } else { $key = $source . ":" . $dest; } push @{$calls{$key}}, $line; } foreach my $k (sort keys %calls) { print join('', @{$calls{$k}}),"\n\n"; }