Re: Using unix commands in perl?
by McDarren (Abbot) on Oct 06, 2007 at 05:02 UTC
|
- Whenever you are talking about unique "anything", almost invariably you need a hash.
- Sorting is achieved by using the sort command.
Post some sample data, and whatever code you already have, and you can probably get some more specific help.
Cheers,
Darren :) | [reply] |
A reply falls below the community's threshold of quality. You may see it by logging in. |
Re: Using unix commands in perl?
by erroneousBollock (Curate) on Oct 06, 2007 at 05:04 UTC
|
Something like this (assuming you have the records as an array of simple strings):
my %seen;
my @result = sort map { $seen{$_}++ ? () : $_ } @records;
You may need to pass a block to sort to make the sort more specific to your records.
If you really want to use the unix commands (say for speed), then you should investigate the use of the '|' modifier with the open built-in function.
-David
| [reply] [d/l] |
Re: Using unix commands in perl?
by Himi (Novice) on Oct 06, 2007 at 05:24 UTC
|
Hi David
I tried the code sample you posted but
it gives an error
Argument "10.60.0.114" isn't numeric in ne at test.pl line 42 (#1)
Can you please tell me how to fix this.
Thanks,
Himi | [reply] |
|
|
Yeah, I just updated my post to reflect that :-)
Try this:
use warnings;
use strict;
use Net::IPAddr;
open(file_info,$file) or die "Can't open $file ";
my @records;
while (<file_info>) {
my ( $src_ip, $src_port ) = /IP\s+(\d+(?:\.\d+){3})\.(\d+)/;
my ( $dst_ip, $dst_port ) = />\s+(\d+(?:\.\d+){3})\.(\d+)/;
push @records, [$src_ip , $src_port , $dst_ip , $dst_port];
}
close(file_info);
my %seen;
my @result =
map { $_->[5] }
sort {
$a->[0] != $b->[0] ? $a->[0] <=> $b->[0]
: $a->[1] != $b->[1] ? $a->[1] <=> $b->[1]
: $a->[2] != $b->[2] ? $a->[2] <=> $b->[2]
: $a->[3] <=> $b->[3]
}
map { $seen{$_->[4]}++ ? () : $_ }
map { [ip2num($_->[0]), $_->[1], ip2num($_->[2]), $_->[3], join(',',
+@$_), $_ ] }
@records;
print join(' ',@$_)."\n" for @results;
[4] is the stringified record for efficient existence tests.
[5] is the original record format for better re-use.
-David
Updated: made this node more stand-alone.
| [reply] [d/l] [select] |
A reply falls below the community's threshold of quality. You may see it by logging in.
|
A reply falls below the community's threshold of quality. You may see it by logging in. |
Re: Using unix commands in perl?
by bruceb3 (Pilgrim) on Oct 06, 2007 at 07:56 UTC
|
On your system you will never have duplicates if you are including the source IP and port, the destination IP and port because those four components must be unique on your system.
As an example;
If you have a service listening on a particular port and multiple incoming connections are made from the same external host, the destination IP and port will be the same (your server) and the source IP address will be the same but the source port will be different for each connection. | [reply] |
Re: Using unix commands in perl?
by Himi (Novice) on Oct 06, 2007 at 05:09 UTC
|
Hi ,
The code i have writtenis as follows :
open(file_info,$file) or die "Can't open $file ";
while (<file_info>)
{
my ( $src_ip, $src_port ) = /IP\s+(\d+(?:\.\d+){3})\.(\d+)/;
my ( $dst_ip, $dst_port ) = />\s+(\d+(?:\.\d+){3})\.(\d+)/;
print "$src_ip , $src_port , $dst_ip , $dst_port \n" ;
}
close(file_info);
This displays the source ip, port, destination ip and port
i need to sort these records and take the uniq ones and display them
Himi | [reply] [d/l] |
|
|
Update: actually the following not going to be quite correct... need to pack the IP addresses as integers for the sort... so a more generalised (schwartzian) transform is probably better. See my next post in this thread.
use warnings;
use strict;
open(file_info,$file) or die "Can't open $file ";
my @records;
while (<file_info>) {
my ( $src_ip, $src_port ) = /IP\s+(\d+(?:\.\d+){3})\.(\d+)/;
my ( $dst_ip, $dst_port ) = />\s+(\d+(?:\.\d+){3})\.(\d+)/;
push @records, [$src_ip , $src_port , $dst_ip , $dst_port];
}
close(file_info);
my %seen;
my @result =
sort {
$a->[0] != $b->[0] ? $a->[0] <=> $b->[0]
: $a->[1] != $b->[1] ? $a->[1] <=> $b->[1]
: $a->[2] != $b->[2] ? $a->[2] <=> $b->[2]
: $a->[3] <=> $b->[3]
}
map { $seen{(join(',',@$_))}++ ? () : $_ } @records;
print join(' ',@$_)."\n" for @result;
-David
| [reply] [d/l] |
Re: Using unix commands in perl?
by Himi (Novice) on Oct 06, 2007 at 05:50 UTC
|
Hi,
Thanks David .. it works great!!
I dont have much perl experience
infact im a java programmer but i have been
assigned a task that has to be done in perl and its
very urgent so i needed help.
Thanks so much all of you! :)
Himi | [reply] |
|
|
| [reply] |
Re: Using unix commands in perl?
by Prof Vince (Friar) on Oct 06, 2007 at 13:10 UTC
|
| [reply] [d/l] |
Re: Using unix commands in perl?
by Himi (Novice) on Oct 06, 2007 at 05:39 UTC
|
Hi,
Is there another work around for this?
unfortunately i dont have the Net/IPAddr.pm in my perl package.
Himi | [reply] |
|
|
| [reply] |
Re: Using unix commands in perl?
by Cop (Initiate) on Oct 06, 2007 at 05:13 UTC
|
If you are on Unixish OS, just run the command, and don't involve Perl. Always use the best tool. If you are not on Unix, just ignore this.
| [reply] |
|
|
If you're not on unix, install uniq and sort
| [reply] |