ファイル読み込みでの変数領域の問題と見栄えの良いif文の作成方法

このQ&Aのポイント
  • ファイルの読み込み処理が上手くいかず、変数の領域が壊れている可能性があります。
  • if文を複数使用して条件に合う品名を取り出すことはできますが、見栄えが良くありません。
  • 変数の領域の問題と見栄えの良いif文の作成方法についてご教示ください。
回答を見る
  • ベストアンサー

ファイルの読み込み処理が上手くいきません。

aaaフォルダ配下のファイルfruits.csv(タブ区切り2列)の1列目の内容が@dbline[1]の内容と等しいものについて、2列目の内容を$Hinmeiに取り出すプログラムを以下のように作成しましたが、他の変数の領域を壊しているようです。何が問題なのかご教示下さい。 因みにif文を何個も使用して条件に合うものの品名を取り出すことはできますが、if文が増えてしまい、見栄えが良くありません。 open (FILE,"../aaa/fruits.csv”); while (<FILE>){ chomp $_; @data=split(/\t/,$_); if(@dbline[1] eq @data[0]) { $Hinmei=$data[1]; last; } } close(FILE);

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

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

  • ベストアンサー
  • heburusu
  • ベストアンサー率85% (140/164)
回答No.1

ひとつ気になる点として、配列要素を参照するときは@ではなく$を使います。 >if(@dbline[1] eq @data[0]) { ではなく if($dbline[1] eq $data[0]) { が正しいと思います。

参考URL:
http://www.envinfo.uee.kyoto-u.ac.jp/user/susaki/perl/array.html
takahide39
質問者

お礼

ありがとうございます。 chomp $_; でグローバル変数に値を設定後、他の処理で参照していたことが原因でした。

関連するQ&A

  • 効率の良いデータ照合のさせ方

    2つのCSVファイル(どちらもデータ件数が1000件を超える)を照合して SQL文の発行の有無を処理するプログラムを組んでいます。↓ open(ファイル1, ファイル1の場所) || die("$!"); while(<ファイル1>){ chomp($_); @data_1 = split(/,/, $_); open(ファイル2, ファイル2の場所) || die("$!"); while(<ファイル2>){ chomp($_); @data_2 = split(/,/, $_);   # ここでファイル1の指定した列のデータとファイル2の指定した列のデータ照合しています。↓   # ($data_1[列]、$data_2[列]) if(($data_1[0] == $data_2[5]) and ($data_1[1] == $data_2[3]) and ($data_1[3] == $data_2[4]) and ($data_1[4] == $data_2[0])){ #insert文     #update文 } } } 上記のような組み方をすると、やはり実行速度がかなり遅くなりました。 8分ぐらい処理にかかってしまいました; 効率的な処理のさせ方ということで、関数などを調べているのですが、 これという関数も見つからず困っています。 プログラムの組み方自体に問題があるとは思うのですが・・ なにぶん、経験が浅いというのもあり・・・; 何か良い方法をご存知の方、ご指導お願いします。

    • ベストアンサー
    • Perl
  • ファイル操作について

    別スレ立てているので、ルール違反になっちゃいますかね? もしそうであればゴメンナサイ… sub fanc{ my @array = @_; my $ag = shift @array; my $n1 = 'AAA.csv'; my $n2 = 'BBB.csv'; my $n3 = 'CCC.csv'; my $n4 = 'DDD.csv'; my $n5 = 'EEE.csv'; ・ opendir(DIR, "C:/Program Files/Apache Group/Apache2/cgi-bin/test");my @pairs = readdir(DIR); close(DIR); if($ag == 1){@files = grep(/$n1/,@pairs); } if($ag == 2){@files = grep(/$n2/,@pairs); } if($ag == 3){@files = grep(/$n3/,@pairs); } if($ag == 4){@files = grep(/$n4/,@pairs); } if($ag == 5){@files = grep(/$n5/,@pairs); } if($ag == 6){@files = grep(/$n6/,@pairs); } ・ $dfile1 = $files[0]; open(IN,"$dfile1") or exit; chomp(my $row01 = <IN>); chomp(my $row02 = <IN>); chomp(my $row03 = <IN>); chomp(my $row04 = <IN>); chomp(my $row05 = <IN>); chomp(my $row06 = <IN>); ・ close(IN); my @col01 = split(/,/, $row01); my @col02 = split(/,/, $row02); my @col03 = split(/,/, $row03); ・ ・ こういったコードをもっと短く、書くやり方を知りたいです。 grepでヒットするのが複数の場合もあるため、当初はForeach文とフOpenで配列@filesに入った ファイルを全て展開して、配列、又は変数に格納しようと思ったのですが、どうやって複数の配列をOpen関数で扱えばいいのか解りません。 もしそうでなければ、現在は一つのファイルに対しての処理ですが、残ったファイルに関しても関数を回す方法があれば、ご教授願えませんか??あ、あと、CODE(xxxxxx)ってなんのことでしょう?

    • ベストアンサー
    • Perl
  • ファイルの読み込みと出力

    ファイルの読み込みと出力 Perl初心者です。よろしくお願いします。 file.csvのようなファイルを読み込んで、 out.csvのように出力するプログラムを作成しているのですが 途中で変な改行が度々入っているためどうしてもうまくいきません。 (file.csvですが、実際は1500行以上あります。 また、最後に必ずendが入っています。 下記のcsvですがテキスト形式で表示した内容です。) 初歩的な質問で申し訳ありません。 調べる限り調べたのですが分かりませんでした。 どうかよろしくお願いします。 「file.csv」 "2010/1/1","C","こんにちは","田中","end", "2009/10/2","B","おはよう","斉藤","end", "2007/3/20","E","Good mor ning","佐藤","end", "1988/8/16","F","こんばんは","中 村","end", "1999/1/10","A","Hello","木村","end", "2005/9/17","D","おはようご ざいます","斎藤","end", 「out.csv」(このように出力したいです) C,こんにちは,田中,2010/1/1,end, B,おはよう,斉藤,2009/10/2,end, E,Good morning,佐藤,2007/3/20,end, F,こんばんは,中村,1988/8/16,end, A,Hello,木村,1999/1/10,end, D,おはようございます,斎藤,2005/9/17,end, 「今書いているプログラムです」 #!/usr/local/bin/perl use strict; use Fatal qw/ open /; my $csv_file = "file.csv"; my @csv = &readCsvFile($csv_file); open(OUT,">out.csv"); for(my $i=0; $i<=5; $i++){    print OUT $csv[$i][1],",";    print OUT $csv[$i][2],",";    print OUT $csv[$i][3],",";    print OUT $csv[$i][0],",";    print OUT $csv[$i][4],","; } close(OUT); sub readCsvFile {    open(DATA, $_[0]);    while(<DATA>) {      chomp;      push @csv, [ split(/",\"/) ];    }    close(DATA);    return @csv; }

    • ベストアンサー
    • Perl
  • CSVデータの同じファイルに上書きするには。

    CSV形式でデータdata.csvが書いてあります。プログラムを実行して、そのファイルの$data[4]の値が5という数字だった場合は、そこのセルだけ"解除"という文字に置き換えて(ほかに入ってる値ははそのまま)data.csvに上書きしたいのですが、どうもうまくいきません。したのように記述したのですが、どこが間違っているのかがわかりません。。どなたか教えてください。よろしくおねがいします。 #!/usr/bin/perl $file='data.csv'; open(FILE, "$file"); while(<FILE>){ @data = split(/,/, $_); } close(FILE); if($data[4] eq "5"){$data[4] = "解除";} open(OUT, ">$file"); print OUT @data; close(OUT);

  • perl:パターンマッチを使ったifの条件

    perlでパターンマッチを使ったifの条件が必ずTRUEになってしまいます。 以下は条件です。二つのファイルがあって、片方のファイルのある列の文字列と別のファイルのある列の文字列が一致したら一致した行の1列目を出力するというプログラムです。 perl v5.12.3 『oct_gene.csv』は以下のような2列のファイルで、2列目であるalphabetの群は空白で区切られています。文字コードはASCIIです。 1 zinc finger protein of the cerebellum 3 0 stathmin-like 2 . . . . 『RNA.csv』は以下のような3列のファイルで、3列目のalphabet群は同じく空白で区切られています。文字コードはUTF-8です。 1 NM_324891 sin3 associated polypeptide 2 NM_53344 Nanog homeobox . . . open (WRITE, ">RNAseq_Oct.csv"); open(FILE, "RNA.csv"); while($line = <FILE>){ chomp $line; @fact = split /\t/, $line; open(OCT, "oct_gene.csv"); while($octline = <OCT>){ chomp $octline; @oct = split /\t/, $octline; if($fact[2] =~ /$oct[1]/){ print WRITE $fact[2] . "\t" . $oct[1] ."\n"; last; } } close (OCT); } close (FILE); close (WRITE); この中のif文がうまく働かず、whileで繰り返すまでもなく必ず if($fact[2] =~ /$oct[1]/) が成り立ってしまいます。 どなたか詳しい方、どうかご教示願います。 それではよろしくお願いします。

    • ベストアンサー
    • Perl
  • 別データファイルを流し込むタイプのcgiで教えてください。

    http://oshiete1.goo.ne.jp/kotaeru.php3?q=1225153 でフローチャート式のフリーcgiをご紹介頂きました。 データも流し込んでうまく動くようになりました。 このファイルはdataファイルが別にあり $datfile = './heart_sm.dat'; のように定義してから呼び出すタイプです。 別ウィンドウで小窓として表示したいので スクリプトを書き無事動作確認できました。 問題1 結果文が長いので流し込んだテキストの大きさを 変えたいのですが、枠や周りの大きさは 変わるのですが、中の流し込んだテキストは 大きさがかわりません。大きさを変えるには どうすれば良いでしょうか? 問題2 結果文にリンクを張って親ウィンドウに 戻したいのですが、単純にdatfilesに ハイパーリンクを書き込んだだけでは 認識してくれません。 良い方法はありませんか? 長いのでデータを読み込むときを 抜粋して書き込みます。 よろしくお願いします。 #--------------------------------------------------------------- sub read_data{ #データファイルの読み込み open(FILE,"$datfile") or error("データファイルが開けません。"); @data = <FILE>; close(FILE); for(@data){ chomp; next if(/^#/); @data_line = split/<>/; $data_no =$data_line[0]; if($data_no eq $Now_no){$find = 1; last} } if($find){ @data_type = split(/:/,$data_line[1]); if($data_type[0] eq "a"){ $mess1 = $data_line[3]; $Yes_no=@data_type[1]; $No_no=@data_type[2]; out_put1(); } elsif ($data_type[0] eq "b") { $mess1 = $data_line[3]; $Next_no=@data_type[1]; out_put2(); }else{ log_write(); result_print(); } } }

    • ベストアンサー
    • CGI
  • 該当項目表示について

    csvデータの列に%で区切った項目があります。 例) 1行目:aaa%bbb%ccc 2行目:aaa&bbb%ddd 3行目:aaa%bbb 3番目の項目(上記例ではccc、ddd)を 1、2番目の項目に該当させるには以下のスクリプトをどのように 変更すればよろしいのでしょうか? いろいろ調査や変更実行してみましたがうまく動きません。 $find = 0; for($d = 0 ; $d < @TEST ; ++$d) { chomp $TEST[$d]; (@ITEM) = split(/\,/, $TEST[$d]); @T = split(/\%/, @ITEMD[2]); #csvデータ内項目%区切り if($in{'item'} eq @T[0]) { if(($in{'item2'} eq "") or ($in{'item2'} eq "全て")) { @FIND[$find] = $TEST[$d]; $find++; } elsif($in{'item2'} eq @T[1]) { @FIND[$find] = $TEST[$d]; $find++; } } } 上記スクリプトに3番目も含める為にはどのようにすればよいのでしょうか? ご教授お願いいたします。

    • ベストアンサー
    • Perl
  • テキストファイルになにも入っていないのを確認して・・・

    書き込みファイル(.txt、.datなど)は最初データは入っていませんよね。空っぽです。 そのときにある変数に0や1を入れたいのですが、ちゃんと認識してくれません。 書き込みファイルの内容は@txtに入っているとします。ただし、まだデータは1件も書き込まれていません。 foreach (@txt) { chomp; ($id, $tonum, $c_date, $c_status, $chkbox) = split(/,/, $_); if( !$_ ){ $id = 0;} として、$idに0を入れたいと思ったのですが、 記録された内容は、 1,1020,2006/9/14,E,0 ,1020,2006/9/14,B,0 →ココ でした。つまりなにも入っていないのです。 ここに値を入れる方法を教えてください。

    • ベストアンサー
    • Perl
  • CSVファイルの読み込み

    お世話になります。 VBAでCSVファイルを読み込んで処理をしたいのですが、 たとえば下記のようなCSVファイルの場合 2つめの項目が金額セットされており、あらかじめ通貨編集(カンマ編集) がされていて 金額を1つの項目として読み込む事が出来ません。 金額は""でくくってあるのですが、 カンマ区切りのデータと""でくくってあるデータを うまく区別して3つの項目をそれぞれ抽出する事は可能でしょうか? -----以下CSVの内容------ 日付,金額,データ 2007/03/09,"1,200",TEST1 2007/03/09,"12,200",TEST2 2007/03/09,"76,00",TEST3 2007/03/09,"4,5600",TEST4 --------------------------- ちなみに現在はこのようにカンマ区切り指定でデータを抽出してるので うまく出来ません。   'FileNameにはオープンするファイル名がセットされています   Open FileName For Input As   'textlineに1行を読み込む   Line Input #ch1, textline   csvline() = Split(textline, ",") VBAがまだ不慣れな為質問やサンプルが分かりずらいと思いますが よろしくお願いします。

  • excel vbaで複数のcsvファイルの読み込み

    100シート分のcsvファイルのデーターを一つずつ読み込んでexcelにコピーして使用してますが莫大な時間がかかって困ってます。 vbaを使用して作業を簡素化出来る事は出来ないでしょうか? ------------------------------------------ ※ csvの概要 excelで1枚のcsvファイルを開くとA列の11行目から65536行まで数値データがあります。 ※ vbaできたらよいなと思う仕様 そこで、複数のcsvファイルを選択して読み込むとCSV_データと言うSeetのA列の10行目から1枚目のcsvファイル、B列の10行目から2枚目のcsvファイルと言う風に選択した分のcsvを列に続けて数値データを貼り付けしてくれるvbaをご教授していただけると大変助かります。 不躾で申し訳ございませんが宜しくお願い致します。 excel2003 ------------------------------------------

専門家に質問してみよう