2

次の質問で、絶望的な perl の初心者を助けることができる人がいるかどうか疑問に思っていました。私は一日中試してきましたが、私のperlの本が仕事で、Googleに関連するものは何もないように見えます...あるいは、これは本当にばかげているのかもしれません.

次のようなファイルがあります。

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";
4

4 に答える 4

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
于 2012-04-14T14:59:43.300 に答える
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) {"
于 2012-04-14T15:20:52.097 に答える
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
于 2012-04-14T23:17:05.643 に答える
0

これを行う簡単な方法は、perl の push および pop 関数を使用することです。 /push.html ) 各名前 (@bobmonths など) のグローバル配列を保持し、月が見つかるたびにプッシュする必要があります。完了したら、名前と配列を出力します。

while(<>)
{
chomp;
push(@bobmonths, $2)

...
}
print @bobmonths
于 2012-04-14T15:00:54.680 に答える