amit amit - 1 month ago 7
Perl Question

grouping lines and concatenating them into one line in perl

This seems like a basic thing to do, but I can't figure out a simple way doing it without starting building lots of arrays etc. so my apologies if this is too simple.

I have a file of this format:

a,x1
a,x2
a,x3
b,x4
c,x5
c,x6


this is an edge list for a very big graph.
I need to convert it to the following format:

a,x1 x2 x3
b,x4
c,x5 x6


(this is another common format of graphs)

Is there a simple way of doing that in perl? you can assume that all the "a" and "b" are sorted, so once you got to a new starting node (say "b") there will be no going back (e.g. no more edges outgoing from "a")

Any advice would be appreciated.

Answer

Just keep the last "from" node in a variable that survives iterations of the loop.

#!/usr/bin/perl
use warnings;
use strict;

my $last = q();
while (<>) {
    chomp;
    my ($from, $to) = split /,/;
    if ($from ne $last) {
        print "\n" x (1 != $.), $from, ',';
        $last = $from;
    } else {
        print ' ';
    }
    print $to;
}
print "\n";

"\n" x (1 != $.) prevents the newline being printed before the 1st line.

The same as a one-liner:

perl -aF, -ne 'chomp $F[1]; print "\n" x (1 != $.), "$F[0]," if $l ne $F[0];
               print " " x ($l eq $F[0]), $F[1]; $l = $F[0] }{ print "\n"' < input