读取文件,匹配string和格式化在Perl输出

花了很长时间在这,现在正在伤害我的头。 我已经简化了数据文件,但基本上我有5个不同的文件中的一些值,现在想把它们绘制成excel。 因此,线形图的Excel中的格式需要更正。

当前文件看起来像

Report-20140521.csv: Sun, 20 Report-20140530.csv: Sun, 23 Report-20140606.csv: Sun, 24 Report-20140613.csv: Sun, 25 Report-20140621.csv: Sun, 21 Report-20140521.csv: Mon, 22 Report-20140530.csv: Mon, 23 Report-20140606.csv: Mon, 24 Report-20140613.csv: Mon, 24 Report-20140621.csv: Mon, 21 Report-20140521.csv: Tues, 22 Report-20140530.csv: Tues, 23 Report-20140606.csv: Tues, 20 Report-20140613.csv: Tues, 21 Report-20140621.csv: Tues, 21 

我想把这一切弄平,并有五行与每个值类似的值: –

  Sun Mon Tue wed .. Report-20140521.csv: 20 22 22 Report-20140530.csv: 23 23 23 Report-20140606.csv: 24 24 20 Report-20140613.csv: 25 24 21 Report-20140621.csv: 21 21 21 

已经看过使用数组和数组的数组,但无论哪种方式的数据似乎被操纵,并不能得到它使用5个不同的行平坦。 最重要的是,我需要保留文件名,因为这将在以后的excel中被划分为date格式。

因为你的星期值是离散的和有界的,所以我认为哈希散列可以很好地工作。 这可能有一些变种:

 use strict; my %matrix; open IN, 'yourfile.txt' or die $!; while (<IN>) { chomp; my ($report, $val) = split /,/; my ($file, $dow) = split /: /, $report; $matrix{$file}{$dow} = $val; } close IN; my @dow = qw(Sun Mon Tues Wed Thu Fri Sat); foreach my $file (sort keys %matrix) { print $file, "\t"; my $report_ref = $matrix{$file}; foreach my $dow (@dow) { print $$report_ref{$dow}, "\t"; } print "\n"; } 

示例输出:

 Report-20140521.csv 20 22 22 Report-20140530.csv 23 23 23 Report-20140606.csv 24 24 20 Report-20140613.csv 25 24 21 Report-20140621.csv 21 21 21 

这个解决scheme就像你问的那样。 在读取数据时,它使用散列%headers将date名称转换为列号,并生成一个由CSV文件名称键入的散列。 散列的值是值对的数组,每对包含列号和该列的值

一旦数据被消解到哈希中,就会按照文件名的sorting顺序进行扫描。 数组@info被初始化为七个空字段,哈希中的列/值对被用来覆盖那些提供的列

确定文件名的最大长度,并首先用于打印date名称的@headers数组,然后为每个哈希条目指定@info数组

我希望这有帮助

 use strict; use warnings; use List::Util 'max'; my $filename = 'current.txt'; open my $fh, '<', $filename or die qq{Unable to open "$filename" for input: $!}; my @headers = qw/ Sun Mon Tue Wed Thu Fri Sat /; my %headers = map { $headers[$_] => $_ } 0 .. $#headers; my %file_data; while (<$fh>) { next unless my @fields = /(\S[^:]+:)\s+(\w{3})\w*, (\d+)/; my $file = shift @fields; $fields[0] = $headers{ucfirst lc $fields[0]}; push @{ $file_data{$file} }, \@fields; } my $width = max map length, keys %file_data; my $format = "%*s%3s %3s %3s %3s %3s %3s %3s\n"; printf $format, $width, '', @headers; for my $file (sort keys %file_data) { my $days = $file_data{$file}; my @info = ('') x 7; for my $day (@$days) { my ($index, $val) = @$day; $info[$index] = $val; } printf $format, $width, $file, @info; } 

产量

  Sun Mon Tue Wed Thu Fri Sat Report-20140521.csv: 20 22 22 Report-20140530.csv: 23 23 23 Report-20140606.csv: 24 24 20 Report-20140613.csv: 25 24 21 Report-20140621.csv: 21 21 21 

您可以使用数组的散列来存储数据,然后打印出与您的列名相匹配的值(即date):

 use warnings; use strict; open my $in, '<', 'in.txt'; my (%data, @record, @day, @n); while (<$in>){ chomp; my @split = split(/\s/); push @record, $split[0]; $split[1] =~ s/,//g; push @day, $split[1]; push @n, $split[2]; } push @{$data{$record[$_]} }, [ $day[$_], $n[$_] ] for 0 .. $#record; my @days = qw(Sun Mon Tues Wed Thu Fri Sat); print "$_ " foreach (@days); print "\n"; for my $report (sort keys %data){ print "$report\t"; for my $val (@{$data{$report}}){ my ($day, $n) = @$val; foreach(@days){ print "$n\t" if $day eq $_; } print "\n"; } } 

输出:

 Sun Mon Tues Wed Thu Fri Sat Report-20140521.csv: 20 22 22 Report-20140530.csv: 23 23 23 Report-20140606.csv: 24 24 20 Report-20140613.csv: 25 24 21 Report-20140621.csv: 21 21 21