• ベストアンサー

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; } どうかご教示お願いいたします。

  • Perl
  • 回答数3
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.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__ りんご 果物 おれんじ 果物 ばなな 果物 もも 果物 なし 果物 あんず 色

pa_baraban
質問者

お礼

>ひょっとしてこういう結果が欲しかった? そうです! おかげさまで望みのものができました。 >$yy{$1} = $3; ここはもとのままで良かったんですね・・・。 仰るとおり、ハッシュについて分かっていませんでした。 >print "$1\t$2\t\#【$xx{$1}】\n" if (exists $xx{$1} && $yy{$1} eq $2); この辺の書き方もよく分かっていなかったので、 とても参考になりました。 本当に助かりました。ありがとうございます!

その他の回答 (2)

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

関係ないですけど, $xx{$f1} = $f4; #▲ $yy{$f1} = $f3; #▲ ってあってます? いや, $f2 が使われていないなぁと思って.... まあ, これはその前の if 文の中に入れるべきのような気もしますが. 実例が欲しいなぁというのは #1 の通り. あと, 念のためバージョンがあるといいかもしれない.

pa_baraban
質問者

お礼

望みのものができました。 どうもありがとうございました!

pa_baraban
質問者

補足

>$xx{$f1} = $f4; #▲ >$yy{$f1} = $f3; #▲ >ってあってます? いや, $f2 が使われていないなぁと思って.... とりあえず、この時点では$f2はいらないので省略しています。 でも、この部分は#1さんへの捕捉のようにしています。 実例も見ていただけたらありがたいです。 ちなみにバージョンはperl5.8です。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

defined じゃなくて exists で判定すべきだと思うけど 現象が起きるデータがないとなんともいえませんね。

pa_baraban
質問者

補足

すみません、訂正です。 $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つ以上ある時にこの現象がおきるようなのですが、 これは関係なかったようです。 一つしかない「おれんじ」が出てきてるし・・・ 根本的に間違っている気がしてきました。

関連するQ&A

  • マッチした行をランダムに3行出力したい

    毎度お世話になっております。 今夜も躓いてしまってどうにもならないので、お力をお貸しいただけませんでしょうか。 以下のようなリストファイルがあります。 ------------------ 項目1 項目2 ・・・ ------------------ このリストにマッチした行を、リストの項目ごとにランダムに3行選んで出力したいです。 マッチした行を取り出すところまでは、以下のような形でできたのですが、 ここから先をどのように書けばいいのかわかりません。 ------------------ my $list = 'リストファイル'; open (IN, "$list"); my %l; while(<IN>) { chomp; $l{$_}++; } close IN; while(<DATA>) { my ($xx,$yy) = split(/\t/,$_); if (exists($l{$xx})) { # print; # ここから先がわかりません } } __END__ 項目1 N1 項目1 N2 項目2 N3 項目2 N4 項目2 N5 項目1 N6 項目2 N7 項目2 N8 項目2 N9 項目1 N10 ------------------ 以下のような出力結果にしたいです。 ------------------ 項目1 N2 項目1 N6 項目1 N10 項目2 N3 項目2 N5 項目2 N9 ------------------ どうぞよろしくお願いいたします。

    • ベストアンサー
    • Perl
  • 構造体の配列とメンバの配列

    typedef struct _ex_table1 {   int  x[10];   int  y[10]; }ETable1; ETable1 et1; int ans1; for( int a = 0; a < 10; a++ ){   et1.x[a] = a+10;   et1.y[a] = a*2; } for( int b = 0; b < 10; b++ ){   if( et1.x[b] == 15 ){     ans1 = et1.y[b];     break;   }   else{     ans1 = 0;   } } printf( "%d", ans1 ); ///////////////////////////////// typedef struct _ex_table2 {   int xx;   int yy; }ETable2; ETable2 et2[10]; int ans2; for( int aa = 0; aa < 10; aa++ ){   et2[aa].xx = aa+10;   et2[aa].yy = aa*2; } for( int bb = 0; bb < 10; bb++){   if( et2[bb].xx == 15 ){     ans2 = et2[bb].yy;     break;   }   else   {     ans2 = 0;   } } printf("%d", ans2 ); と言う感じに、微妙にソースを書いてみたのですが、 上のメンバ(x,xx)の値が正しいものがあったら、 対応する下のメンバ(y,yy)を出力したいと思っていますが、 構造体を配列にした場合と、構造体メンバを配列にした場合は どのように違うのでしょうか? 私には、同じように思えてしまいます。 どなたか、利点・欠点など教えていただけませんか? よろしくお願い致します。

  • awkで別のファイルを参照して、検索結果を得たい。

    awk初心者です。 あるファイル(targetファイル)に、どのような属性があるのかを検索ファイル(objectファイル)を 使って調べたいのです。そこでawkを使って: targetファイル 5 a c objectファイル 1,aa 2,bb 3,cc 4,dd 5,aa 6,bb 7,cc 8,dd 9,aa 10,bb a,cc b,dd c,aa d,bb e,cc f,dd g,aa h,bb i,cc j,dd 以下のようなスクリプトを作成し mawk32 -f スクリプト target.txt object.txt としたのですが、動作しません。 何らかの御助言を頂ければ幸いです。 #targetファイル読み込み FILENAME == ARGV[1]{ dat1[FNR]=$1 no_dat1 = FNR } #objectファイル読み込み FILENAME == ARGV[2]{ dat2[FNR]=$0 no_dat2 = FNR } #相互に検索 END{ for (i = 1; i <= no_dat1; i++){ for (j = 1; j <= no_dat2; j++){ if (dat1[i]~/dat2[j]/) { print dat1[i],dat2[j] } }}}

  • redoを実行するとスカラー変数の値がundefになってしまうのはどうしてでしょうか?

    はじめまして。 質問があります。 まずは以下のコードを見てください。 ---------------------------------------------------------------- use strict; use warnings; open(FILE,'redo01.txt') or die "$!"; while(my $line = <FILE>) { print "undef\n" unless( defined($line) ); chomp($line); if($line =~ /---$/) { $line .= <FILE>; redo; } print $line,"\n"; } close(FILE); ---------------------------------------------------------------- --redo01.txt---------------------------------------------------- zero--- one--- two--- three--- four ---------------------------------------------------------------- ファイルから一行を読み込んできてスカラー変数$lineに代入して、 redoを実行しながら$lineの値をどんどん連結していき最後に文字列を 表示させようと思っていたのですが、なぜかredoを実行後 ループ内の先頭行に制御を移してから$lineの値を調べてみると、 undefになってしまいます。事実、chomp()関数やパターンマッチ、 print関数を実行すると、エラーになってしまいます。なぜ$lineの値 がundefになってしまうのでしょうか?どうかご教授お願いします。

    • ベストアンサー
    • Perl
  • 深い要素の取り出し方

    下のような場合、一般的にはforeachを使うと思いますが、 $sample[cc]->[0]->[xx]の要素である「さ」だけを取り出す場合はどのようにしたら取り出せるのでしょうか? $sample [aa] => あ [bb] => か [cc] => Array   (    [0] => Array     (      [xx] => さ      [yy] => た     )    [1] => Array     (      [xx] => な      [yy] => は     )   )

    • ベストアンサー
    • PHP
  • 「HSP」で左クリック判定がうまく判定されません

    マウスの左クリック判定があいまいに判定されます。 原因が不明なので教えて下さい。(初心者なので。。) /* 初期化 */ screen 0,600,400 cls 4 /* MAIN */ *main xx = mousex : yy = mousey if (xx < 0):xx = 0 if (xx > 600):xx = 600 if (yy < 0):yy = 0 if (yy > 400):yy = 400 if (cc1 == 0){ // cc1 カラー設定のフラグ cc2++ // cc2 カラー設定 if (cc2>254){ cc1=1 } } if (cc1 == 1){ cc2-- if (cc2==0){ cc1=0 } } getkey k1,2 // 右クリック getkey k2,1 // 左クリック wait 1 if ( k1 == 1){ // 右クリック判定 cls 4 } if ( k2 == 1){ // 左クリック判定 flg = flg^0x01 // ビット反転 } if ((xx != xx2)||(yy != yy2)){ // マウス移動確認 xx2 = xx yy2 = yy pos 0,0 color 0,0,0 boxf 0,0,110,20 color 255,255,255 print "xx="+xx+":yy="+yy // マウス位置情報 if (flg == 0):goto *move // 描画ルーチン } goto *main *move color cc2,cc2,cc2 line xx,yy,xx,yy+10 // 四角を描画 line xx,yy,xx+10,yy line xx+10,yy,xx+10,yy+10 line xx,yy+10,xx+10,yy+10 goto *main

  • PEAL if AA or BB

    ######## AAかBBがあったらprint PEALで  AA || BB   AA か BB って事はわかりましたが AA と BB 両方ともあった場合は? ######## AAかBBがあったらprint if (($in{'AA'}) || ($in{'BB'})) { print "$in{'AA'}"; print "$in{'BB'}"; }

    • ベストアンサー
    • Perl
  • データからある文字列の次の行を出力するには

    perlの初心者です。はじめまして。 質問タイトルそのままなのですが、データからある文字列の次の行を出力するにはどのような記述をすればよろしいでしょうか?よろしくお願いします。 ・データは1ファイルで2000あります。1つのデータは[X,Y]で始まり、次の[X,Y]の前までになります。 ・出力はCSVファイル。 ・DAT errがあった場合はその次の行を出力。なかったら、DAT列は空白にする。 #!/bin/perl open(FILE,"<$ARGV[0]"); open(OUT,">$ARGV[0].csv"); ########################## err count ########################### print OUT "X,Y,NUMBER,DAT,\n"; while(<LOG>){ if($_ =~ /X=(.+)\,Y=(.+)/){ chomp($_); print OUT "\n$1,$2,"; } if($_ =~ /NUMBER (.+)/){ print OUT "$1,"; } if($_ =~ /DAT err/){ print OUT "PASS,0,"; } } close(OUT);

    • ベストアンサー
    • Perl
  • SQL構文を手助けしてください

    (1)のようなテーブルデータを(2)のように表示したいと思います。 AA,BB,CC,DD,EEは列名としてください。 (1) AA BB CC DD EE __________________________ 00 01 2004/01/01 XX YY 01 00 2004/01/01 XE YD 01 00 2004/01/05 XZ YZ 02 01 2004/01/10 X2 YE 02 02 2004/01/05 XW YI 02 02 2004/01/06 XF YL (2) AA BB CC DD EE __________________________ 00 01 2004/01/01 XX YY 01 00 2004/01/05 XZ YZ 02 01 2004/01/10 X2 YE 02 02 2004/01/06 XF YL <条件> AAとBBでキーを作り、CCのMAXの該当レコードを表示したい。 SELECT AA,BB,MAX(CC),DD,EE FROM TEST_TABLE GROUP BY AA,BB というような感じかなと思ったのですが、「GROUP BY の式ではありません」と怒られてしまいます。 どなたか簡単なやり方をご存知で無いでしょうか?

  • until文

    初歩的な質問ですみません。 file1 あいうえお かきくけこ さしすせそ たちつてと   ・   ・   ・   ・ なにぬねの はひふへほ まみむめも があります。 ・・・・の部分を消したくて、以下のようなプログラムを書いたのですが、 上手くいきません。 教えてください。お願いします。 @ARGV = ("file1"); $^I = ".bak"; while(<>){ $a = 0; chomp($_); if(/たちつてと/){ $a = 1; until(/なにぬねの/){ $a = 1; } }; if(/なにぬねの/){ $a = 0; }; if($a = 1){ }else{ print "$_\n"; }; };

    • ベストアンサー
    • Perl

専門家に質問してみよう