花了很长时间,现在它正在伤害我的头脑。我已经简化了数据文件,但基本上我有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中条带化为日期格式。
答案 0 :(得分:0)
我认为哈希的散列对此很有效,因为你的星期值是离散的和有限的。一些变体可能有用:
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
答案 1 :(得分:0)
您可以使用数组散列来存储数据,然后打印出与您的列名匹配的值(即白天):
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
答案 2 :(得分:0)
此解决方案按您的要求执行。它使用散列%headers
在读入数据时将日期名称转换为列号,并生成由CSV文件名称键入的散列。哈希值是值对的数组,每对由列号和该列的值组成
将数据消化到散列后,将按文件名的排序顺序进行扫描。数组@info
初始化为七个空字段,哈希中的列/值对用于覆盖提供的列
确定文件名的最大长度,并在打印@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