问题是在每个新行读取一个带有值的文件。文件内容类似于
3ssdwyeim3,3ssdwyeic9,2017-03-16,09:10:35.372,0.476,EndInbound
3ssdwyeim3,3ssdwyfyyn,2017-03-16,09:10:35.369,0.421,EndOutbound
3ssdwyfxc0,3ssdwyfxfi,2017-03-16,09:10:35.456,0.509,EndInbound
3ssdwyfxc0,3ssdwyhg0v,2017-03-16,09:10:35.453,0.436,EndOutbound
使用第一个逗号之前的字符串作为键,并在最后一个和最后一个逗号之间输入字符串值
即。对于第一行3ssdwyeim3成为关键和0.476值。
现在,如果密钥存在,我们循环遍历每一行,我们必须连接用逗号分隔的值。
因此,对于下一个新行,因为密钥已存在,密钥仍为3ssdwyeim3
但值已更新为0.476,0.421.
最后,我们必须在文件中打印键和值。
我已经编写了一个代码来实现相同的功能,如下所示。
sub findbreakdown {
my ( $out ) = @_;
my %timeLogger;
open READ, "out.txt" or die "Cannot open out.txt for read :$!";
open OUTBD, ">$out\_breakdown.csv" or die "Cannot open $out\_breakdown.csv for write :$!";
while ( <READ> ) {
if ( /(.*),.*,.*,.*,(.*),.*/ ) {
$btxnId = $1;
$time = $2;
if ( !$timeLogger{$btxnId} ) {
$timeLogger{$btxnId} = $time;
}
else {
$previousValue = $timeLogger{$btxnId};
$newValue = join ",", $previousValue, $time;
$timeLogger{$btxnId} = $newValue;
}
}
foreach ( sort keys %timeLogger ) {
print OUTBD "$_ ,$timeLogger{$_}\n";
}
}
close OUTBD;
close READ;
}
然而有些东西出了问题,它就像这样打印
3ssdwyeim3,0.476
3ssdwyeim3,0.476,0.421
3ssdwyeim3,0.476,0.421
3ssdwyfxc0,0.509
3ssdwyeim3,0.476,0.421
3ssdwyfxc0,0.509,0.436
3ssdwyeim3,0.476,0.421
3ssdwyfxc0,0.509,0.436
预期是:
3ssdwyeim3,0.476,0.421
3ssdwyfxc0,0.509,0.436
答案 0 :(得分:3)
您的程序运行正常,但在处理每一行后,您将打印整个哈希的当前状态。
因此,您在拥有完整的值集之前打印哈希键,并且您有许多重复的行。
如果将打印的foreach
循环移动到程序的末尾(或者只是使用调试器来检查变量),您会发现散列的最终状态正是您所期望的。
编辑:我以前认为问题出在下面,但这是因为我误读了你问题中的示例数据。
这个正则表达式并不理想:
if (/(.*),.*,.*,.*,(.*),.*/) {
.*
贪婪并且会尽可能匹配(包括一些逗号内容)。因此,如果任何行包含六个以上以逗号分隔的项目,则第一个匹配组中将包含多个项目。这可能不是您实际数据中的问题,但它不是编写代码的理想方式。表达式比必要的更模糊。
最好这样写:
if (/^([^,]*),[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$/) {
只能匹配六个项目的行。
或者考虑在输入行上使用split,这将是一个更清洁的解决方案。
答案 1 :(得分:1)
这比你做的简单得多。您可以将每一行拆分为字段,然后使用push
将值添加到与该键对应的列表中
我相信您可以将其修改为从外部文件而不是DATA
文件句柄中读取吗?
use strict;
use warnings 'all';
my %data;
while ( <DATA> ) {
my @fields = split /,/;
push @{ $data{$fields[0]} }, $fields[-2];
}
for my $key ( sort keys %data ) {
print join(',', $key, @{ $data{$key} }), "\n";
}
__DATA__
3ssdwyeim3,3ssdwyeic9,2017-03-16,09:10:35.372,0.476,EndInbound
3ssdwyeim3,3ssdwyfyyn,2017-03-16,09:10:35.369,0.421,EndOutbound
3ssdwyfxc0,3ssdwyfxfi,2017-03-16,09:10:35.456,0.509,EndInbound
3ssdwyfxc0,3ssdwyhg0v,2017-03-16,09:10:35.453,0.436,EndOutbound
3ssdwyeim3,0.476,0.421
3ssdwyfxc0,0.509,0.436