ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I have the following perl script to insert the data into a hash of arrays, but I can't seem to figure out how to put the source IPs all on one line and eliminate duplicate IPs.
Code:
#!/usr/bin/perl
use warnings;
use strict;
our %HoA = ();
open(LOG, '<', 'names_ips.csv');
while( my $line = <LOG>)
{
my ($who, $where) = split /:\s*/, $line;
chomp($where,$who);
$HoA{$who} = [ $where ];
}
for my $items ( keys %HoA )
{
print "$items,@{ $HoA{$items} }\n";
}
If someone could point me in the right direction, I would appreciate it!
Perhaps someone else can help you with Perl. I'd personally just use awk for this:
Code:
awk '
BEGIN {
RS = "[\t\n\v\f\r ]*[\n\r][\t\n\v\f\r ]*"
FS = ",[\t\v\f ]*"
users = 0
}
(NF > 1) {
if (!($1 in list)) {
user[++users] = $1
list[$1] = ","
}
for (i = 2; i <= NF; i++)
if (length($i) > 0)
if (!index(list[$1], "," $i ","))
list[$1] = list[$1] $i ","
}
END {
for (u = 1; u <= users; u++) {
thisuser = user[u]
thislist = list[thisuser]
sub(/^,+/, "", thislist)
sub(/,+$/, "", thislist)
printf("%s:%s\n", thisuser, thislist)
}
}' logfile
This script saves user names in the user array, IP address list for each user (keyed by the user name) as a string in list array, with a comma before and after each IP address. An address is added only if it does not exist in the list; the commas make sure partial matches are not considered.
Also, note that colon (:) as a separator is a very bad idea. It makes things very difficult when you start using IPv6 addresses -- and you will, sooner or later. I recommend using either a comma or a pipe (|) instead.
Last edited by Nominal Animal; 05-19-2011 at 04:20 PM.
I haven't tested this, but I think it looks better. The HoA needs elements added as they are found, for each user. When they are printed, they can be first turned into a scalar, using join.
Code:
#!/usr/bin/perl
use warnings;
use strict;
our %HoA = ();
open(LOG, '<', 'names_ips.csv');
while( my $line = <LOG>)
{
my ($who, $where) = split /:\s*/, $line;
chomp($where,$who);
push @{$HoA{$who}}, $where;
}
for my $user ( keys %HoA )
{
my $ipList = join ",", $HoA{$user};
print "$user:$ipList\n";
}
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.