Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

rearranging text

by texuser74 (Monk)
on Dec 02, 2003 at 03:08 UTC ( [id://311496]=perlquestion: print w/replies, xml ) Need Help??

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

Dear Friends,

I have a ascii text file with the following kind of text

a, 1
aa, 3
aa, 5
aa, 8
b, 2
b, 3
bb, 5

this i want to arrange as

a, 1
aa, 3, 5, 8
b, 2, 3
bb, 5

my input file is already in sorted form, but how to arrange the numbers like this

please help

Replies are listed 'Best First'.
Re: rearranging text
by Zaxo (Archbishop) on Dec 02, 2003 at 03:18 UTC

    Collect your data in a hash of arrays, pushing on the data as it is seen,

    my %hash; while (<IN>) { chomp; my @foo = split /, /; push @{$hash{$foo[0]}}, 0+$foo[1]; } for (sort keys %hash) { print OUT join ', ', $_, @{$hash{$_}}; print OUT $/; }
    The 0+$foo[1] is there to make the value numeric and so strip trailing whitespace.

    After Compline,
    Zaxo

Re: rearranging text
by Roger (Parson) on Dec 02, 2003 at 03:19 UTC
    How about this? ;-)
    use strict; my $prev; while (<DATA>) { next if /^\s*$/; chomp (my ($curr, $val) = split /,\s+/); print $prev ? "\n" : "", $prev = $curr if $curr ne $prev; print ", $val"; } print "\n"; __DATA__ a, 1 aa, 3 aa, 5 aa, 8 b, 2 b, 3 bb, 5
      Hey Roger,

      Can you enlighten on the purpose of '\s+' in the split expression?

        \s means match a single space, \s+ means match one or more spaces.

        In the example below:
        use strict; use Data::Dumper; my $string = 'a, 1, 2, 3'; my @split_comma = split /,/, $string; print "\@split_comma =>", Dumper(\@split_comma); my @split_comma_space = split /,\s+/, $string; print "\@split_comma_space =>", Dumper(\@split_comma_space);
        Notice in the output -
        @split_comma =>$VAR1 = [ 'a', ' 1', ' 2', ' 3' ]; @split_comma_space =>$VAR1 = [ 'a', '1', '2', '3' ];
        Splitting with comma only leaves spaces in array elements, while splitting with comma+space leaves no spaces in array elements.

        What split /,\s+/ does is to set the separator as comma followed by 1 or more spaces, thus eliminating the spaces from the result.

Re: rearranging text
by BUU (Prior) on Dec 02, 2003 at 03:14 UTC
    my %all; while(<>) { my ($k,$v)=split/,/; $all{$k}.=",$v"; } print map { "$_, $all{$_} "} keys %all;

      This leads to possibly ugly output as there will be an extra comma in the output

      Also will a value appear more than once, and should the values be sorted as well? Im thinking a HoH might be overkill, but another (better?) way to do it.

      my %all; while (<>) { s/\s+//g; my($k, $v) = split /,/; next unless defined $k and defined $v; $all{$k}{$v}++; } for ( sort keys %all ) { print "$_, ", join(', ', sort keys %{ $all{$_} }), "\n"; }

      use perl;

Re: rearranging text
by Zed_Lopez (Chaplain) on Dec 02, 2003 at 08:00 UTC

    or, getting sillier...

    while (<DATA>) { print /(\d+)/ ? ", $1" : $s{$_}++ ? '' : $a++ ? "\n$_" : $_ for spli +t /\s*,\s*/; } print "\n"; __DATA__ a, 1 aa, 3 aa, 5 aa, 8 b, 2 b, 3 bb, 5
Re: rearranging text
by sphere0001 (Initiate) on Dec 02, 2003 at 18:30 UTC
    I'm pretty new to perl as you can probably tell from my solution, but here you go anyway.
    #!/usr/bin/perl -w use strict; my $someDatFile = 'datfile.dat'; #the file you need read in open( DATFILE, $someDatFile ) or die "Cannot open $someDatFile"; my $currentPrefix; while( <DATFILE> ) { my( $prefix, $postfix ) = split ( /,/, $_ ); &cleanUp( \$prefix ); &cleanUp( \$postfix ); if( ( !$currentPrefix ) or ( $currentPrefix ne $prefix ) ) { if( $currentPrefix ) { print "\n"; } $currentPrefix = $prefix; print "$prefix, $postfix"; } else { print ", $postfix"; } } print "\n"; close( DATFILE ); sub cleanUp { my $ref = shift; $$ref =~ s/^\s*//; $$ref =~ s/\s*$//; }
Re: rearranging text
by kesterkester (Hermit) on Dec 02, 2003 at 15:56 UTC
    Here's how I'd do it (pretty similar to Zaxo's and Roger's):
    my %hash; while (<DATA>) { chomp ( my ( $key, $val ) = split /,\s+/ ); push @{$hash{$key}}, $val; } print "$_ ", join( ", ", @{$hash{$_}} ), "\n" foreach sort keys %hash;
Re: rearranging text
by Willard B. Trophy (Hermit) on Dec 03, 2003 at 15:38 UTC
    Doesn't the troff/TeX utility "makeindex" do this for you?

    --
    bowling trophy thieves, die!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://311496]
Approved by rob_au
Front-paged by davido
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (6)
As of 2024-04-23 19:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found