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

Hi, I'm trying to format a table with data like
<data> aaa bbb 123 aaa ccc 234 aaa ddd 345 bbb ccc 456 bbb ddd 567 ccc ddd 678 ... </data>
Output format:
aaa bbb ccc ddd aaa - 123 234 345 bbb - 456 567 ccc - 678
Can't figure out the way... Can you give me suggestions? Thanks in advance, Antonio

Replies are listed 'Best First'.
Re: table from repeated strings text
by GotToBTru (Prior) on Jul 13, 2015 at 18:25 UTC

    What have you tried so far?

    Check out the tutorials page here for help in getting started. You'll want to check out the sections on file handling. The split command will probably be useful in breaking apart those input lines into individual values; you'll want to look into hashes and arrays as a way to access those values.

    Dum Spiro Spero
Re: table from repeated strings text
by AnomalousMonk (Archbishop) on Jul 13, 2015 at 18:59 UTC

    Also, please note that Perlmonks recognizes no such thing as a <data> tag. Please Update your original post to use  <c> ... </c> or  <code> ... </code> tags around code, data and input/output. Please see Markup in the Monastery and Writeup Formatting Tips.


    Give a man a fish:  <%-(-(-(-<

Re: table from repeated strings text
by Aldebaran (Curate) on Jul 13, 2015 at 18:21 UTC

    Hi Antonio,

    I tried to determine whether you're using column/row order or row/column order and got contradictions either way. Can you say a few more words about the order the original data is in, as well as the order you would like to manipulate the output into? Are there holes in the data?

Re: table from repeated strings text
by Anonymous Monk on Jul 13, 2015 at 19:06 UTC

    wild guess - is this the kind of thing you are looking for ?

    #!/usr/bin/perl # http://perlmonks.org/?node_id=1134550 use warnings; use strict; my (@left, %left, @top, %top, %values); my $all = ''; while(<DATA>) { $all |= $_ for my ($left, $top, $value) = split; $left{$left}++ or push @left, $left; $top{$top}++ or push @top, $top; $values{$left}{$top} = $value; } my $len = length $all; my $fmt = join(' ', map "%${len}s", 0..@top) . "\n"; printf $fmt, '', @top; for my $left (@left) { printf $fmt, $left, map $values{$left}{$_} // '', @top; } __DATA__ aaa bbb 123 aaa ccc 234 aaa ddd 345 bbb ccc 456 bbb ddd 567 ccc ddd 678

    prints

    bbb ccc ddd aaa 123 234 345 bbb 456 567 ccc 678

      OK, I forgot the -'s

      #!/usr/bin/perl # http://perlmonks.org/?node_id=1134550 use warnings; use strict; my (@left, %left, @top, %top, %values); my $all = ''; while(<DATA>) { $all |= $_ for my ($left, $top, $value) = split; $left{$left}++ or push @left, $left; $top{$left}++ or push @top, $left; $top{$top}++ or push @top, $top; $values{$left}{$top} = $value; } my $len = length $all; my $fmt = join(' ', map "%${len}s", 0..@top) . "\n"; printf $fmt, '', @top; for my $left (@left) { printf $fmt, $left, map $left eq $_ ? '-' : $values{$left}{$_} // ' +', @top; } __DATA__ aaa bbb 123 aaa ccc 234 aaa ddd 345 bbb ccc 456 bbb ddd 567 ccc ddd 678

      prints

      aaa bbb ccc ddd aaa - 123 234 345 bbb - 456 567 ccc - 678
Re: table from repeated strings text
by Laurent_R (Canon) on Jul 13, 2015 at 19:00 UTC
    Your example only gives a vague idea of what you are trying to do. Please explain how you get to the results you are looking for.

    Showing what you have tried so far would also help us understanding what you are trying to do.

      I guess the OP is looking for
      aaa bbb ccc ddd aaa - 123 234 345 bbb - 456 567 ccc - 678
      poj
Re: table from repeated strings text
by Marshall (Canon) on Jul 14, 2015 at 11:59 UTC
    Perhaps:
    #!usr/bin/perl -w use strict; my %HOA; my %seen; while (<DATA>) { my($name1,$name2,$value) = split; push ( @{$HOA{$name1}}, $value) unless $seen{$value}++; push ( @{$HOA{$name2}}, $value) unless $seen{$value}++; } foreach my $name (sort keys %HOA) { print "$name - ", "@{$HOA{$name}}","\n"; } =Program Prints: aaa - 123 234 345 bbb - 456 567 ccc - 678 =cut __DATA__ aaa bbb 123 aaa ccc 234 aaa ddd 345 bbb ccc 456 bbb ddd 567 ccc ddd 678
Re: table from repeated strings text
by Not_a_Number (Prior) on Jul 14, 2015 at 17:43 UTC

    Or even:

    use 5.12.0; use warnings; my %HoA; while ( <DATA> ) { my @got = split; push @{ $HoA{ $got[0] } }, $got[2]; } say "$_ - @{$HoA{$_}}" for sort keys %HoA; __DATA__ aaa bbb 123 aaa ccc 234 aaa ddd 345 bbb ccc 456 bbb ddd 567 ccc ddd 678

    Update: ...which could be shortened to (the no doubt less efficient, splitting the same line twice):

    my %HoA; push @{ $HoA{ ( split )[0] } }, ( split )[2] while <DATA>;