我是Perl的初学者,目前正致力于使用Perl脚本来自动化我们的一些任务。我正在处理的一个脚本涉及从我们的系统中提取性能数据,将其存储在CSV文件中并生成Excel图形。在处理完这个脚本几天之后,我设法将提取的数据转换成CSV,但是现在,我很难设法转换数据!我已经看过这个帖子(感谢dalton的脚本):stackoverflow thread,但我似乎无法应用它。
基本上,我的CSV文件包含每行的每日数据,列数为一天中的小时数(24小时):
29-Aug-2013,3.68,3.63,3.75,3.65,3.65,3.11,3.34,2.74,2.83,2.52,3.19,4.24,3.84,3.61,3.69,2.96,2.76,2.91,3.70,3.82,3.70,3.54,2.54,3.90
30-Aug-2013,3.46,2.97,3.83,3.55,3.41,3.47,3.32,2.81,2.80,2.32,3.17,3.60,3.63,3.83,3.67,2.92,2.34,3.21,3.45,3.51,3.57,3.46,3.52,4.19
31-Aug-2013,3.19,3.50,4.01,3.91,3.71,3.33,3.20,2.95,2.90,2.37,3.07,3.48,2.86,3.29,3.22,2.52,1.83,2.83,3.54,3.49,3.62,3.59,3.54,3.31
01-Sep-2013,2.88,3.16,2.79,2.90,3.78,3.18,3.26,2.84,3.21,2.50,3.35,3.78,3.30,4.04,3.80,3.07,3.23,3.54,3.30,3.43,3.56,3.48,3.60,3.78
02-Sep-2013,3.28,2.92,3.89,3.78,3.54,3.09,3.08,2.79,2.87,2.43,2.70,3.64,3.79,3.88,3.88,3.28,2.90,3.37,3.25,3.60,3.45,3.39,2.84,4.07
03-Sep-2013,3.31,2.54,3.59,3.59,3.50,3.10,2.98,2.63,3.20,2.53,2.92,3.42,3.76,3.07,3.41,2.42,2.12,3.19,3.32,3.08,3.63,3.50,3.71,3.75
04-Sep-2013,3.64,3.48,2.86,3.57,3.68,3.53,3.34,2.89,2.79,2.64,3.30,4.04,4.17,3.70,3.81,2.96,3.41,3.48,3.66,3.05,3.23,3.41,3.15,4.31
现在,我想转置它,以便我将写入新CSV文件的结果数据如下所示:
Time,29-Aug-2013,30-Aug-2013,1-Sep-2013,2-Sep-2013,3-Sep-2013,4-Sep-2013
01:00,3.68,3.46,3.19,2.88,3.28,3.31,3.64
02:00,3.63,2.97,3.50,3.16,2.92,2.54,3.48
03:00,3.75,3.83,4.01,2.79,3.89,3.59,2.86
...
现在,我的脚本看起来像这样:
my @rows = ();
my @transposed = ();
open F1,"D:\\Temp\\perf_data.csv";
while(<F1>) {
chomp;
push @rows, split [ /,/ ];
}
#print @rows;
for my $row (@rows) {
for my $column (0 .. $#{$row}) {
push(@{$transposed[$column]}, $row->[$column]);
}
}
for my $new_row (@transposed) {
for my $new_col (@{$new_row}) {
print $new_col, ",";
}
print "\n";
}
我甚至无法从中获得结果!有人可以帮我提一下如何做到这一点吗?提前谢谢!
答案 0 :(得分:3)
你犯了一个简单而又严重的错误。
split [ /,/ ]
应该是
[ split /,/ ]
split
的语法是
split /PATTERN/, EXPR, LIMIT
后两者是可选的。你正在做的是将匿名数组引用为PATTERN
,这很可能会被字符串化为类似ARRAY(0x54d658)
的内容。结果是该线未被分割,并且整条线被推到阵列上。稍后,这将导致$row
的取消引用失败并显示错误
Can't use string ("29-Aug-2013,3.68,3.63,3.75,3.65,"...) as an ARRAY ref while "
strict refs" in use at foo.pl line 18, <F1> line 7.
答案 1 :(得分:0)
这是我的Perl程序,用于将行数据转置为列。 一行以标题名称开头,后跟一个或多个值。 就我而言,我需要从标题中删除日期(mm / dd / yyyy),以便标题字段的其余部分在多行中是唯一的。
sub usage { << "EOF";
Convert rows to columns.
Remove dates from column headings.
Usage:
perl $0
Example:
$0 data-to-transpose.txt
Source data:
header1, row1Value1, row2Value2
header2, row2Value1
header3 11/31/2011, row3Value1, row3Value2
Output:
header1, header2, header3
row1Value1, row2Value1, row3Value1
row1Value2, , row3Value2
EOF
}
#
#-------------------------------------------------------------------------------
use 5.010;
use strict;
use warnings;
# use Data::Dumper;
sub printColumns;
my $inFile = shift or die usage();
# @ARGV = ('.') unless @ARGV;
my @headers; # Order list of column headers
my %data; # map{colHeader, arrayColSourceData }
my $colCnt = 0; # maximum number of columns in source data, header, value1, value2, ....
my $printColHeaders = 1;
my %hasharray; open (my $fh, "<", $inFile) or die "can't open the $inFile";
while (<$fh>) {
chomp;
my @parts = split /,/;
if (@parts > 1) {
# Remove date from heading field
(my $header = $parts[0]) =~ s/[0-9]+\/[0-9]+\/[0-9]+//;
if (!exists $data{$header}) {
push @headers, $header;
}
my $have = $data{$header};
if (defined $data{$header}) {
if ($printColHeaders == 1) {
$printColHeaders = 0;
foreach my $col (@headers) {
print "$col,";
}
print "\n";
}
printColumns();
foreach my $col (@headers) {
$data{$col} = undef;
}
}
$data{$header} = \@parts;
$colCnt = (@parts > $colCnt) ? @parts : $colCnt;
}
}
printColumns();
print "\n";
foreach my $col (@headers) {
print "$col,";
}
print "\n";
#### Subs
sub printColumns() {
for my $row (1 .. $colCnt-1) {
foreach my $colHeader (@headers) {
my $colData = $data{$colHeader};
if (defined $colData) {
my $len=@$colData;
if (defined $colData && $row < @$colData) {
print "$colData->[$row], ";
} else {
print ", ";
}
} else {
print ", ";
}
}
print "\n";
}
}