我想知道是否有人可以通过以下问题帮助perl的绝望新手。我一整天都在努力,但是在工作中使用我的perl书,我似乎无法在谷歌中找到任何相关内容......或者说这真的很愚蠢。
我有一个类似于以下内容的文件:
Bob April
Bob April
Bob March
Mary August
Robin December
Robin April
我之后的输出文件是:
Bob April April March
Mary August
Robin December April
因此,它按照每个人显示的顺序列出每个月。
我尝试将它变成哈希,但当然它不会让我有重复,所以我想我想为每个名字都有数组(在这个例子中,Bob,Mary和Robin)。 我害怕上传我一直试图调整的代码,因为我知道这将是可怕的错误。我想我需要定义(?)数组。这是正确的吗?
非常感谢任何帮助,我保证在此期间我会更多地研究perl。
感谢您的时间,耐心和帮助。
#!/usr/bin/perl -w
while (<>) {
chomp;
if (defined $old_name) {
$name=$1;
$month=$2;
if ($name eq $old_name) {
$array{$month}++;
}
else {
print "$old_name";
foreach (@array) {
push (@array, $month);
print "\t@array";
}
print "\n";
@array=();
$array{$month}++;
}
}
else {
$name=$1;
$month=$2;
$array{month}++;
}
$old_name=$name;
}
print "$old_name";
foreach (@array) {
push (@array, $month);
print "\t@array";
}
print "\n";
答案 0 :(得分:2)
对于这么简单的任务,您的代码看起来过于复杂。
use strict;
use warnings;
my %hash;
while (<DATA>) {
my ($name, $mon) = split;
push @{$hash{$name}}, $mon;
}
for my $name (keys %hash) {
my @months = @{$hash{$name}};
print "$name\t@months\n";
}
__DATA__
Bob April
Bob April
Bob March
Mary August
Robin December
Robin April
答案 1 :(得分:1)
你有点亲近。您确实希望使用名称为键的哈希,但正如您所看到的,对于每个名称,您要存储数组的月份,因此您要使用的数据结构是哈希数组(或者更确切地说是数组引用,因为这是在Perl中实现的)
在此期间,请不要养成使用全局变量的习惯 - 100%的代码应该在开头有“use strict; use warnings;
”,并且本地作用域(my
)变量。
use strict;
my %data;
my @sorted_names; # Only needed if you care which order to print the results
while (<>) {
chomp;
my ($name, $month) = split(/s+/);
if (! $data{$name}) {
# Initialize to empty array reference if first time.
# Not required - perl will do it for you
$data{$name} ||= [];
# Only needed if you want to print results in the same order of names as input.
push @sorted_names, $name;
}
push @{ $data{$name} }, $month;
}
foreach my $name (@sorted_names) {
print "$name\t" . join(" ", @{ $data{$name} }) . "\n";
}
# If don't care about name order, just do "foreach my $name (keys %data) {"
答案 2 :(得分:1)
<强> 脚本: 强>
#!/usr/bin/perl
use strict;
use warnings;
my %content;
open my $fh, '<file.txt' or die $!;
while (<$fh>) {
push @{$content{$1}}, $2 if /^(\S+)\s+(\S+)\s*$/;
}
close $fh;
foreach (keys %content) {
print $_, "\t";
foreach my $item (@{$content{$_}}) {
print "$item ";
}
print "\n";
}
或
#!/usr/bin/perl
use strict;
use warnings;
my %content;
open my $fh, '<file.txt' or die $!;
while (<$fh>) {
push @{$content{$1}}, $2 if /^(\S+)\s+(\S+)\s*$/;
}
close $fh;
print "$_\t@{$content{$_}}\n" for keys %content;
或
#!/usr/bin/perl
use strict;
use warnings;
my %content;
open my $fh, '<file.txt' or die $!;
s/^(\S+)\s+(\S+)\s*$/{push @{$content{$1}}, $2}/e for <$fh>;
close $fh;
print "$_\t@{$content{$_}}\n" for keys %content;
<强> 输出: 强>
Bob April April March
Mary August
Robin December April
包含内容的文件file.txt
:
Bob April
Bob April
Bob March
Mary August
Robin December
Robin April
答案 3 :(得分:0)
一种简单的方法是使用perl的push和pop函数。(因为你开始使用perl:http://perldoc.perl.org/functions/pop.html,http://perldoc.perl.org/functions/push.html) 你应该为每个名字保留一个全局数组(例如@bobmonths),并在每次找到一个月时推送一个月。 完成后,打印出名称和数组:
while(<>)
{
chomp;
push(@bobmonths, $2)
...
}
print @bobmonths