#!/usr/bin/perl -w
use strict;
# transpose_for_qdf.pl
# Utility script written to bypass the Excel 255-column limitation in preparing
# data. The idea is to prepare the data in transposed format and then use this
# script to transpose it.
# Invoked with the name of a text file, this program transposes it by treating a tab character
# as a separator that forces placement of the words into different
# rows of the output file. Thus a line such as
# XX 3.0 #$#* -2e9
# will be turned into a column
# XX
# 3.0
# #$#*
# -2e9
# Empty cells will be transposed properly.
# The transposed data will be written to a new file with suffix x.txt
# Clare Nelson, KSU Plant Path, 12.21.06
# NOTE that it will NOT work right with tab-separated fields containing spaces. Don't
# allow any spaces except as separators.
my $sXposed_insert = "_x";
my $sUsageMsg = "Usage: perl $0
";
if (@ARGV < 1) { die $sUsageMsg;}
my ($infile) = @ARGV;
my $outfile = decorate_name($infile, $sXposed_insert);
my $input_2D_ref = file_to_2D_arr($infile);
transpose_array_2D_to_file($input_2D_ref, $outfile);
## SUBROUTINES ##
sub decorate_name # inserts a substring before the file suffix
{
my ($name, $insert) = @_;
my $pos = rindex($name, '.'); # find first "." from right end
if ($pos > 0)
{ my $prefix = substr($name, 0, $pos);
my $suffix = substr($name, $pos);
return $prefix . $insert . $suffix;
}
else {return $name . $insert;}
}
# loads a file with whitespace-separated lines into an array of references to arrays.
# Lines need not have the same numbers of words.
# CN changed to split on single whitespace, 11.2.09
sub file_to_2D_arr
{
my $infile = shift;
my @arr_2D;
my $count = 0;
open (INFILE, $infile) || die "Cannot open \"$infile\" : $!";
while (my $line = )
{ my @temp_arr = split(/\s/, $line);
$arr_2D[$count++] = \@temp_arr;
}
close INFILE;
return \@arr_2D;
}
# Writes a 2D array to a string in transposed form. Doesn't assume all subarrays are of same length.
# Added precision and missing symbol CN 2.27.10
sub transpose_array_2D_to_text
{
my ($arr_2D_ref, $precision, $missing_symbol) = @_;
if (defined($precision))
{ $precision = "\%\." . $precision . "f";}
if (!defined($missing_symbol))
{ $missing_symbol = "";}
my ($printval, $text);
my $max_row_len = find_max_row_len($arr_2D_ref);
for (my $col = 0; $col < $max_row_len; $col++)
{
foreach my $row_arr_ref(@$arr_2D_ref)
{
my $val = $row_arr_ref->[$col];
if (!defined($val)) {$printval = $missing_symbol;}
elsif (defined($precision) && $val !~ /\D/) # is numerical
{ $printval = sprintf($precision, $val);}
else
{ $printval = $val;}
$text .= "$printval\t";
}
$text .= "\n";
}
return $text;
}
# Writes a 2D array to a file in transposed form. Doesn't assume all subarrays are of same length.
sub transpose_array_2D_to_file
{
my ($arr_2D_ref, $outfile, $do_append) = @_;
my $text = transpose_array_2D_to_text($arr_2D_ref);
writefile($text, $outfile, $do_append);
}
sub find_max_row_len
{
my $arr_2D_ref = shift;
my $max_len = 0;
foreach my $row_arr_ref(@$arr_2D_ref)
{
my $len = @$row_arr_ref;
if ($len > $max_len) {$max_len = $len;}
}
return $max_len;
}
sub writefile
{
my ($stuff, $outfile, $do_append) = @_;
my $how_char = $do_append ? ">>" : ">";
open(OUTFILE, "$how_char$outfile") || die "Cannot open \"$outfile\" : $!";
print OUTFILE $stuff;
close OUTFILE;
}