user1987607
user1987607

Reputation: 2157

How to split a variable in Perl on tab character?

I have a variable $results generated by the following foreachloop

my $result = "";
foreach $c1(sort {$a<=>$b} keys %info ) {
    $result .= $c1 . "\t" .
      join(',',@{$info{$c1}->{var1}}) . "\t" . 
      join(',',@{$info{$c1}->{var2}}) . "\n";
}

If I print the results it looks like this

a    b    c
c    d    e
f    g    h

So there are three columns seperated by \t and the lines are separated by \n. I now want to split this $results variable by tab, to end up with 3 columns. I tried to do this with a while loop, but it's not working

while($result){
    my @columns = split("\t"); 
}

What am I doing wrong?

Upvotes: 2

Views: 22816

Answers (2)

Borodin
Borodin

Reputation: 126742

What you have written will produce an endless loop, since while ($result) { ... } will continue as long as $result is a true value, which yours is. Furthermore, if you did split it as you wanted you would get

("a", "b", "c\nd", "e", "f\ng", "h", "i")

which I presume isn't what you want.

You shouldn't join all your data together with tabs and then split it again. Keep it as separate items. Something like

my @results;

foreach my $c1 (sort { $a <=> $b } keys %info ) {
  push @results, [
    $c1,
    join ',', @{ $info{$c1}{var1} },
    join ',', @{ $info{$c1}{var2} }
  ];
}

Then you will have an array of arrays corresponding to the originally printed data. You can print it out for diagnostic purposes using Data::Dump if you wish.


Update

Since you want to retain the values of the first column, which are the sorted keys of the has, you may as well save those separately before looping over them. Perhaps this code suits you better?

my @keys = sort { $a <=> $b } keys %info;
my @results;

foreach my $c1 ( @keys ) {
  push @results, [
    $c1,
    join ',', @{ $info{$c1}{var1} },
    join ',', @{ $info{$c1}{var2} }
  ];
}

Now @keys is the list of values that you wanted.

Upvotes: 4

tripleee
tripleee

Reputation: 189638

Without an argument, split splits the value of $_. You want split(/\t/, $result);

Also, the while looks wrong. Perhaps you want

for my $r (split (/\n/, $result)) {
    @columns = split (/\t/, $r);
    :

Upvotes: 6

Related Questions