说,我有一个文件,其中包含以下行,其中包含“TIMESTAMP”“NAME”:
10:00:00鲍勃
11:00:00汤姆
11:00:20弗雷德
11:00:40乔治
12:00:00比尔
我想读取这个文件,将每个小时中出现的名称分组到一行,然后将修改后的行写入文件,例如。
10:00:00鲍勃 11:00:00汤姆,弗雷德,乔治 12:00:00比尔
答案 0 :(得分:2)
在这样的块中逐行读取文件:
while(<>) {
# ... do something with the line in $_
# specifically, collect the hour and name
# ignoring malformed lines
if (/(\d\d):\d\d:\d\d\s+(\w+)/) {
my $hour = $1;
my $name = $2;
}
}
并通过在内部if
块
$people{$hour} = $people{$hour} . ", " . $name
最后,在循环外部,打印哈希:
while ( my ($time, $names) = each(%people) ) {
print $time . ":00:00 " . $names ."\n";
}
(这是未经测试的,但这是我将采取的基本方法。)
答案 1 :(得分:2)
在下面的grouped_by_hour
中,对于文件句柄中的每一行,如果它有时间戳和名称,我们push
使用sprintf
命名到与时间戳小时相关联的数组上如果一个时间戳为03:04:05
而另一个时间戳为3:9:18
,则将小时标准化。
sub grouped_by_hour {
my($fh) = @_;
local $_;
my %hour_names;
while (<$fh>) {
push @{ $hour_names{sprintf "%02d", $1} } => $2
if /^(\d+):\d+:\d+\s+(.+?)\s*$/;
}
wantarray ? %hour_names : \%hour_names;
}
标准化小时数也允许我们使用默认比较进行排序。下面的代码将输入放在DATA
令牌之后的特殊__DATA__
文件句柄中,但在实际代码中,您可以调用grouped_by_hour $fh
。
my %hour_names = grouped_by_hour \*DATA;
foreach my $hour (sort keys %hour_names) {
print "$hour:00:00 ", join(", " => @{ $hour_names{$hour} }), "\n";
}
__DATA__
10:00:00 Bob
11:00:00 Tom
11:00:20 Fred
11:00:40 George
12:00:00 Bill
输出:
10:00:00 Bob 11:00:00 Tom, Fred, George 12:00:00 Bill
答案 2 :(得分:2)
考虑到这一点,根据原始问题的评论,同一小时的所有条目都是连续的,文件太大而无法放入内存中,我会完全免除哈希 - 如果原始文件太大而不适合内存,然后包含其所有数据的哈希可能也会太大。 (是的,它正在压缩数据,但散列本身会增加大量开销。)
我的解决方案,然后:
#!/usr/bin/env perl
use strict;
use warnings;
my $current_hour = -1;
my @names;
while (my $line = <DATA>) {
my ($hour, $name) = $line =~ /(\d{2}):\d{2}:\d{2} (.*)/;
next unless $hour;
if ($hour != $current_hour) {
print_hour($current_hour, @names);
@names = ();
$current_hour = $hour;
}
push @names, $name;
}
print_hour($current_hour, @names);
exit;
sub print_hour {
my ($hour, @names) = @_;
return unless @names;
print $hour, ':00:00 ', (join ', ', @names), "\n";
}
__DATA__
10:00:00 Bob
11:00:00 Tom
11:00:20 Fred
11:00:40 George
12:00:00 Bill
答案 3 :(得分:0)
以下是完整的解决方案。
my @readings = (
"10:00:00 Bob",
"11:00:00 Tom",
"11:00:20 Fred",
"11:00:40 George",
"12:00:00 Bill",
);
my %hours;
for my $line (@readings) {
$line =~ /^(\d{2}).*?([a-zA-Z]+)/;
push(@{$hours{$1}}, $2);
}
for my $hour (sort keys %hours) {
print "$hour:00:00 ";
print join ", ", @{$hours{$hour}};
print "\n";
}
这导致:
10:00:00 Bob
11:00:00 Tom, Fred, George
12:00:00 Bill