- ベストアンサー
definedの使い方が間違ってますか?
こんばんは。 色々試してみたのですが、どうしてもうまくいかないので質問させてください。 リストの$f1とファイルの$aaがマッチして、 かつリストの$f3とファイルの$bbがマッチした場合に、 $f4を付け加えてprintしたいのですが、 ★マークの処理で、リストの$f3とファイルの$bbがマッチしていないものまで printされてしまうことがあります。 $aaとマッチするものがリストに2つ以上ある時にこの現象がおきるようなのですが、 どの辺を直したらよいのかわかりません。 definedの使い方がおかしいのでしょうか? 見よう見まねで書いたので、▲マークあたりの指定も自信がありません。 #リスト読み込み open LIST, "./list" or die; while (<LIST>) { chomp; if (/(.*) (.*) (.*) (.*)/) { $f1 = $1; $f2 = $2; $f3 = $3; $f4 = $4; } $xx{$f1} = $f4; #▲ $yy{$f1} = $f3; #▲ } close LIST; #ファイル読み込み if ($#ARGV >= 0) { @files = @ARGV; } foreach $file (@files) { open FILE, $file; while (<FILE>) { chomp; if (/^([^t]+)\t(.*)$/) { $aa = $1; $bb = $2; if (defined($xx{$aa})) { if (defined($yy{$bb})) { # ★ print "$aa\t$bb\t\#【$xx{$aa}】\n"; } } } } close FILE; } どうかご教示お願いいたします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
ひょっとしてこういう結果が欲しかった? >perl mogera.pl りんご 果物 #【apple】 ばなな 果物 #【banana】 なし 果物 #【pear】 細かな間違いもあるけど、ハッシュを勘違いしているような気もします。 #!/usr/bin/perl # -*- coding: utf8 -* use strict; use warnings; use feature 'say'; use utf8; binmode STDOUT, ':encoding(cp932)'; my $list = "りんご リンゴ 果物 apple おれんじ オレンジ 色 orange ばなな バナナ 果物 banana もも モモ 花 peach もも モモ 木 peach なし ナシ 果物 pear あんず アンズ 木 apricot あんず アンズ 実 apricot"; my %xx; my %yy; foreach my $line (split qq{\n}, $list) { if ($line =~ /(.*) (.*) (.*) (.*)/) { $xx{$1} = $4; $yy{$1} = $3; } } while (my $line = <DATA>) { if ($line =~ /^([^t]+)\t(.*)$/) { print "$1\t$2\t\#【$xx{$1}】\n" if (exists $xx{$1} && $yy{$1} eq $2); } } __END__ りんご 果物 おれんじ 果物 ばなな 果物 もも 果物 なし 果物 あんず 色
その他の回答 (2)
- Tacosan
- ベストアンサー率23% (3656/15482)
関係ないですけど, $xx{$f1} = $f4; #▲ $yy{$f1} = $f3; #▲ ってあってます? いや, $f2 が使われていないなぁと思って.... まあ, これはその前の if 文の中に入れるべきのような気もしますが. 実例が欲しいなぁというのは #1 の通り. あと, 念のためバージョンがあるといいかもしれない.
お礼
望みのものができました。 どうもありがとうございました!
補足
>$xx{$f1} = $f4; #▲ >$yy{$f1} = $f3; #▲ >ってあってます? いや, $f2 が使われていないなぁと思って.... とりあえず、この時点では$f2はいらないので省略しています。 でも、この部分は#1さんへの捕捉のようにしています。 実例も見ていただけたらありがたいです。 ちなみにバージョンはperl5.8です。
- sakusaker7
- ベストアンサー率62% (800/1280)
defined じゃなくて exists で判定すべきだと思うけど 現象が起きるデータがないとなんともいえませんね。
補足
すみません、訂正です。 $yy{$f1} = $f3; #▲ ↓ $yy{$f3} = $f3; こう書いたのでした・・・。 現象が起きるデータは、例えば、 <リストの内容> りんご リンゴ 果物 apple おれんじ オレンジ 色 orange ばなな バナナ 果物 banana もも モモ 花 peach もも モモ 木 peach なし ナシ 果物 pear あんず アンズ 木 apricot あんず アンズ 実 apricot <ファイルの内容> # 区切り文字はタブ りんご 果物 おれんじ 果物 ばなな 果物 もも 果物 なし 果物 あんず 色 <出力結果> りんご 果物 #【apple】 おれんじ 果物 #【orange】 ばなな 果物 #【banana】 もも 果物 #【peach】 なし 果物 #【pear】 あんず 色 #【apricot】 リストの$f3と一致しない以下の3つはprintされないようにしたいのですが、 printされてしまいます・・・。 おれんじ もも あんず 簡略化してみると、 >$aaとマッチするものがリストに2つ以上ある時にこの現象がおきるようなのですが、 これは関係なかったようです。 一つしかない「おれんじ」が出てきてるし・・・ 根本的に間違っている気がしてきました。
お礼
>ひょっとしてこういう結果が欲しかった? そうです! おかげさまで望みのものができました。 >$yy{$1} = $3; ここはもとのままで良かったんですね・・・。 仰るとおり、ハッシュについて分かっていませんでした。 >print "$1\t$2\t\#【$xx{$1}】\n" if (exists $xx{$1} && $yy{$1} eq $2); この辺の書き方もよく分かっていなかったので、 とても参考になりました。 本当に助かりました。ありがとうございます!