• 締切済み

perlでアドバイスをお願いします。

あるテキストファイルが以下の内容で記述されているとします。 a   file1 a   file1 a   file1 b   file1 b   file1 b   file1 c   file2 c   file2 d   file2 d   file2 e   file2 e   file2 f   file3 f   file3 f   file3 上記のように列が二つあるテキストファイルについて、 2列目のfile名が1列目のどの値とひもづいて いるかを処理するperlプログラムを作ることを考えます。 出来上がったperlによって上記テキストファイルを処理した結果は、 file1は aとb file2は cとdとe file3は f とひもづいていることが分かる ということにしたいです。 これをperlプログラムで書くとき、条件として 一行一行を読みとるとき if ( $_ =~ /(\S+)\s+(\S+)/ ){ を使っています。 そのため$1と$2に現在行の1列目,2列目が与えられた後、 ハッシュと配列を組み合わせて考えた場合どのようにすれば いいのでしょうか。 また仮にテキストファイルの続きが存在し、 1列目がg 、2列目がfile1 の行があるとき 2列目で既に出てきた同じfile名はエラーとすることも考えた 場合どう記述するのか合わせてお願い致します。 長くなってしまい申し訳ないのですが、 ご指導ご鞭撻宜しくお願い致します。

みんなの回答

  • kumoz
  • ベストアンサー率64% (120/185)
回答No.3

%hash = ( file1 => ['a', 'b'], file2 => ['c', 'd', 'e'], file3 => ['f'],); ハッシュと配列の組み合わせで作るとすれば、上記のようなデータ構造になると思います。なお、遠く離れたファイル名をエラーにする場合は、現在処理中のファイル名を記憶しておく必要があります。 use strict; open FH, 'xxx.txt' or die $!; my ($ckey, %hash) = (''); while (<FH>) { if ($_ =~ /(\S+)\s+(\S+)/) { if ($ckey eq $2) { push @{$hash{$ckey}}, $1 unless grep { $1 eq $_ } @{$hash{$ckey}}; } elsif (exists $hash{$2}) { print "$2 は既に出てきたためエラーとして処理をストップしました\n"; } else { $ckey = $2; push @{$hash{$ckey}}, $1; } } } close FH; print "$_は ", join('と', @{$hash{$_}}), "\n" foreach sort keys %hash;

torajiro123
質問者

お礼

こちらからの回答が遅くなり失礼しました。 ご回答感謝致します。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

「また」以降で何を言っているのかわかりません. その場合に, どうして「エラー」なのですか? 「既に出てきた同じfile名」というなら, 2行目で「エラー」にならないとおかしいですよ. ちなみに本題については基本的に http://okwave.jp/qa/q7913474.html で書かれているようにハッシュのハッシュでいくのが無難.

  • ORUKA1951
  • ベストアンサー率45% (5062/11036)
回答No.1

while(@line){ if ( $_=~/(\S+)\s+(\S+)/ ){ %check{$2}=$1; # =>じゃない } この場合keyがない場合は自動的に作られますから、すでにkeyが存在しているか否かを判断して代入しなければなりません。 unless( exists $check{$1}){}