電子書籍の厳選無料作品が豊富!

あるテキストファイルが以下の内容で記述されているとします。
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名はエラーとすることも考えた
場合どう記述するのか合わせてお願い致します。

長くなってしまい申し訳ないのですが、
ご指導ご鞭撻宜しくお願い致します。

A 回答 (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;
    • good
    • 0
この回答へのお礼

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

お礼日時:2013/05/21 10:00

「また」以降で何を言っているのかわかりません. その場合に, どうして「エラー」なのですか? 「既に出てきた同じfile名」というなら, 2行目で「エラー」にならないとおかしいですよ.



ちなみに本題については基本的に
http://oshiete.goo.ne.jp/qa/7913474.html
で書かれているようにハッシュのハッシュでいくのが無難.
    • good
    • 0

while(@line){


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

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!