Pivot text file with Perl

I have a tab delimited file that has three rows of data. There are multiple columns with data. It looks like this:

Month    Year    PartnerName   Air    Hotel
12           2013  Partner A          10    20
12           2013  Partner B           5      3

I need to somehow transpose the file so it ends up like this:

12        2013      Partner A       Air      10
12        2013      Partner A       Hotel    20
12        2013      Partner B       Air         5
12        2013      Partner B       Hotel    3

So it is taking the "data" columns and pivoting those to rows.
Who is Participating?
dlnewman70Connect With a Mentor Author Commented:
# use strict;
use warnings;

use Fcntl ':flock'; # contains LOCK_EX (2) and LOCK_UN (8) constants
$beforefile = $ARGV[0];
$afterfile = $ARGV[1];

open (INFILE, $beforefile);
open (OUTFILE,">", $afterfile);

my $line = <INFILE>;
my @header_item = split(/\t/, $line);
my $size = $#header_item + 1;
die("Invalid header line.\n") if (@header_item < 2);

my %new_header_item = ();
my %data = ();

while ($line = <INFILE>)
    my @item = split(/\t/, $line);

      my @h = sort keys(%new_header_item);
      my $counter = 4;

      while ($counter < $size)
      print OUTFILE $item[0]."\t".$item[1]."\t".$item[2]."\t".$item[3]."\t".$header_item[$counter].' '.join(' ', @h).$item[$counter]."\n";
      $counter = $counter + 1;

perl -ane '@h?((@h[0,1]=splice@F,-2),print "@F @h[-2,0]\n@F @h[-1,1]\n"):(@h=@F)' file
dlnewman70Author Commented:
I am trying to run this on Windows. Would there be any reason that this would cause a

β€œCan't find string terminator ”'β€œ anywhere before EOF at -e line 1”

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

dlnewman70Author Commented:
I have swapped the single quote with double quotes and the double quotes with single quotes and it appears to run, but I don't see the changes on the file.
perl -ane "@h?((@h[0,1]=splice@F,-2),print qq'@F @h[-2,0]\n@F @h[-1,1]\n'):(@h=@F)" file

If you want to change file:
perl -i.bak -ane "@h?((@h[0,1]=splice@F,-2),print qq'@F @h[-2,0]\n@F @h[-1,1]\n'):(@h=@F)" file
dlnewman70Author Commented:
The above code that I wrote seemed to work better for our solution.
What makes a solution 'better' for you?
On the example in the original question, the code in http:#a39836803 fails with Invalid header line.
and if the spaces in the example are changed to tabs, it still does not produce the result you said you wanted it to ends up like.
It also has several expressions that produce no useful effect.

Do you want three 'fixed' tab delimited columns and an unlimited number of 'transposed' columns?
perl -F"\t" -lane '$"="\t";if(@h){@h{@h}=splice@F,3;print "@F\t$_\t$h{$_}" for @h}else{@h=@F[3..$#F]}'  beforefile > afterfile
dlnewman70Author Commented:
Savant, "better" for us is basically giving me the desired result. I am not fully versed either on the single line solution. Still learning...

On the solution ozo provided it wasn't giving me the exact results I was expecting.

I appreciate you all jumping in for support and for ideas.
On the example in the original question, the code in http:#a39837072 gave me the desired result that was specified, and the code in http:#a39836803 did not.
If you wish to clarify either the initial conditions or the desired result, we can adjust our suggestions accordingly.
dlnewman70Author Commented:
This code did what I needed it to do.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.