- 締切済み
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名はエラーとすることも考えた 場合どう記述するのか合わせてお願い致します。 長くなってしまい申し訳ないのですが、 ご指導ご鞭撻宜しくお願い致します。
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- kumoz
- ベストアンサー率64% (120/185)
%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;
- Tacosan
- ベストアンサー率23% (3656/15482)
「また」以降で何を言っているのかわかりません. その場合に, どうして「エラー」なのですか? 「既に出てきた同じfile名」というなら, 2行目で「エラー」にならないとおかしいですよ. ちなみに本題については基本的に http://okwave.jp/qa/q7913474.html で書かれているようにハッシュのハッシュでいくのが無難.
- ORUKA1951
- ベストアンサー率45% (5062/11036)
while(@line){ if ( $_=~/(\S+)\s+(\S+)/ ){ %check{$2}=$1; # =>じゃない } この場合keyがない場合は自動的に作られますから、すでにkeyが存在しているか否かを判断して代入しなければなりません。 unless( exists $check{$1}){}
お礼
こちらからの回答が遅くなり失礼しました。 ご回答感謝致します。