Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Perl中转置CSV数据_Perl_Csv_Transpose - Fatal编程技术网

在Perl中转置CSV数据

在Perl中转置CSV数据,perl,csv,transpose,Perl,Csv,Transpose,我是一名Perl初学者,目前正在编写一个Perl脚本来自动化我们的一些任务。我正在编写的一个脚本涉及从系统中提取性能数据,将其存储在CSV文件中,并生成Excel图表。在这个脚本上工作了几天之后,我成功地将提取的数据转换成CSV,但是现在,我在尝试转换数据时遇到了困难!我看过这个帖子(多亏了道尔顿的脚本):,但我似乎无法将它应用到我的案例中 基本上,我的CSV文件每行包含一个每日数据,列为一天中的小时数(24小时): 现在,我想转置它,这样我将写入新CSV文件的结果数据将如下所示: Time,2

我是一名Perl初学者,目前正在编写一个Perl脚本来自动化我们的一些任务。我正在编写的一个脚本涉及从系统中提取性能数据,将其存储在CSV文件中,并生成Excel图表。在这个脚本上工作了几天之后,我成功地将提取的数据转换成CSV,但是现在,我在尝试转换数据时遇到了困难!我看过这个帖子(多亏了道尔顿的脚本):,但我似乎无法将它应用到我的案例中

基本上,我的CSV文件每行包含一个每日数据,列为一天中的小时数(24小时):

现在,我想转置它,这样我将写入新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";
}
现在,我的脚本如下所示:

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";
}
my@rows=();
我的@transposed=();
打开F1,“D:\\Temp\\perf_data.csv”;
while(){
咀嚼;
按@行,拆分[/,/];
}
#打印@行;
对于我的$row(@rows){
对于我的$列(0..$#{$row}){
push(@{$transposed[$column]},$row->[$column]);
}
}
对于我的$new_行(@transposed){
对于我的$new_col(@{$new_row}){
打印$new_col,“,”;
}
打印“\n”;
}

我甚至不能从中得到一个结果!有人能给我一些提示我怎么做吗?提前谢谢

你犯了一个简单但严重的错误

split [ /,/ ] 
应该是

[ split /,/ ]
split
的语法为

split /PATTERN/, EXPR, LIMIT
其中后两个是可选的。您正在做的是将一个匿名数组ref作为
模式
传递,它很可能被字符串化为类似
数组(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.
不能将字符串(“29-Aug-2013,3.68,3.63,3.75,3.65,”…)用作数组引用,而
foo.pl第18行第7行中使用的“严格参考”。

这是我的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";
    } 
}
子用法{1){
#从标题字段中删除日期
(我的$header=$parts[0])=~s/[0-9]+\/[0-9]+\/[0-9]+/;
如果(!exists$data{$header}){
推送@headers,$header;
}
my$have=$data{$header};
if(定义的$data{$header}){
如果($printColHeaders==1){
$printColHeaders=0;
foreach my$col(@headers){
打印“$col”;
}
打印“\n”;
}
printColumns();
foreach my$col(@headers){
$data{$col}=undef;
}
} 
$data{$header}=\@部分;
$colCnt=(@parts>$colCnt)?@parts:$colCnt;
}
} 
printColumns();
打印“\n”;
foreach my$col(@headers){
打印“$col”;
}
打印“\n”;
####潜艇
子列(){
对于我的$row(1..$colCnt-1){
foreach my$colheaders(@headers){
my$colData=$data{$colHeader};
if(定义为$colData){
my$len=@$colData;
if(定义为$colData&&$row<@$colData){
打印“$colData->[$row],”;
}否则{
打印“,”;
}
}否则{
打印“,”;
}
}
打印“\n”;
} 
}

看起来您主要是从中复制代码的。但是你犯了一个严重的错误
split[/,/]
应该是
[split/,/]
.TLP-是的,这就是我在帖子中感谢海报的原因。我相信我在这里要做的是逐行提取我的CSV文件,并将其用作数组的数组。但是,我似乎无法将其放入新数组@rows中。我会试试你的建议,然后告诉你。谢谢TLP-就是这样!它正在工作!非常感谢你的帮助!不客气。我会添加一个答案,这样你就不会在你的历史中遇到一个没有答案的问题。顺便说一句:一些基本规则1)始终使用
use strict;使用警告启动您的脚本2)一旦字段中出现任何不寻常的内容,使用或系列来读取和写入CSV;3) 将输入文件作为脚本的参数,而不是将其硬编码到文件中,这使脚本更易于使用和测试