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

i have a file like
1300018 a1 1300019 a1 1300100 a2 1300101 a2 1300126 a2 1300127 a2 1300128 a2 1300129 a2 1300130 a3 1300131 a3 1300132 a3 1300133 a3
i want it to be like
a1 2file 1300018 1300019 a2 6file 1300100 1300101 1300126 1300127 1300128 1300129 a3 4file 1300130 1300131 1300132 1300133
i know i should use hash to deal with it... but after completed to assign key and value to hash....how to unique a1 column and make uniqued a1 column to corresponding to fist column?

Replies are listed 'Best First'.
Re: question about algorithm
by ikegami (Patriarch) on Jul 23, 2009 at 03:47 UTC
    Assuming the data is sorted as shown, there's no need for a hash. You just have to keep track of the value from the previous row.
    my $prev; while (<$fh>) { my ($field1, $field2) = split; if (!defined($prev) || $prev ne $field2) { print("\n") if !defined($prev); $prev = $field2; print("$field2\n"); } print("$field1\n"); }
Re: question about algorithm
by jwkrahn (Abbot) on Jul 23, 2009 at 04:31 UTC
    $ echo "1300018 a1 1300019 a1 1300100 a2 1300101 a2 1300126 a2 1300127 a2 1300128 a2 1300129 a2 1300130 a3 1300131 a3 1300132 a3 1300133 a3" | perl -lane' push @order, $F[ 1 ] unless $h{ $F[ 1 ] }; push @{ $h{ $F[ 1 ] } }, "$F[ 0 ]\n" }{ print "$_ " . @{ $h{ $_ } } . "file\n", @{ $h{ $_ } } for @order ' a1 2file 1300018 1300019 a2 6file 1300100 1300101 1300126 1300127 1300128 1300129 a3 4file 1300130 1300131 1300132 1300133
Re: question about algorithm
by bichonfrise74 (Vicar) on Jul 23, 2009 at 04:49 UTC
    Try this.
    #!/usr/bin/perl use strict; my %record; while (<DATA>) { my ($key, $val) = split /\s+/; push( @{ $record{$val} }, $key ); } for my $i ( sort keys %record ) { print "\n\n$i " . scalar @{ $record{$i} } . "file\n" . join "\n", @{ $record{$i} }; } __DATA__ 1300018 a1 1300019 a1 1300100 a2 1300101 a2 1300126 a2 1300127 a2 1300128 a2 1300129 a2 1300130 a3 1300131 a3 1300132 a3 1300133 a3
Re: question about algorithm
by Corion (Patriarch) on Jul 23, 2009 at 06:27 UTC
Re: question about algorithm
by perlplayer (Sexton) on Jul 23, 2009 at 11:38 UTC
    how about this sollution
    open FH1, "</users/mhalder/testrun/datafile"; foreach $line (<FH1>){ $line=~s/\s+/:/g; ($fileid,$tag)=split (/\:/,$line); if (defined $filelist->{$tag}){ $filelist->{$tag}->{COUNT}++; $filelist->{$tag}->{FILES}->[($filelist->{$tag}->{COUNT})-1]= +$fileid; } else{ $filelist->{$tag}->{COUNT}=1; $filelist->{$tag}->{FILES}->[($filelist->{$tag}->{COUNT})-1]=$ +fileid; } } print " **** OUTPUT **** \n\n"; foreach $filetag ( sort keys %$filelist){ print "\n$filetag: $filelist->{$filetag}->{'COUNT'} FILES\n\n"; print "LIST OF FILES:\n"; foreach $filename ( @{$filelist->{$filetag}->{FILES}}){ print " $filename\n"; } print; }



    in my code "datafile" holds the lines 1300018 a1
    1300019 a1
    1300100 a2
    1300101 a2
    1300126 a2
    1300127 a2
    1300128 a2
    1300129 a2
    1300130 a3
    1300131 a3
    1300132 a3
    1300133 a3