• 締切済み

csvの内容を配列に入れて個別に変数をつける

はじめまして、お世話になります。 内容はdata.csvを開いて$a1の値が、ban1の時に、 該当の一行を読み出して、カンマ区切りでわかれている順番に、 $a1 $a2 $a3という変数に代入して他のプログラム内で、利用できればと思いますが、 思うように値が取得できません。 下記、参考サイトなどを見ながら、 動作の部分をかいてみました。 まだ理解が浅く、見当はずれな指示があるかもしれませんが、 ご参照いただき具体的な、 ご指摘をいただければと思います。 よろしくお願いいたします。 my $dataFile = 'data.csv'; open FH,"<$dataFile" or error_msg("データファイルが開けません : $!"); flock(FH, LOCK_EX); while(<FH>){ chomp(); my@dummy = split(/,/,$_); if($a1 == $ban1) { $hoge = $_; last; } chop $hoge; ($a1,$a2,$a3,$a4,$a5,$a6,$a7,$a8,$a9,$a10,$a11) = split(/,/); } flock(FH, LOCK_NB); close FH;

  • Perl
  • 回答数5
  • ありがとう数10

みんなの回答

  • Ogre7077
  • ベストアンサー率65% (170/258)
回答No.5

簡単ながら # ファイルを全部読み取り my @records; my $dataFile = 'data.csv'; open FH, "<$dataFile" || die; foreach(<FH>) { chomp(); my @a = split /,/; push @records, \@a; } close FH; # 読み取った行を繰り返し my $size = @records; for (my $i = 0; $i < $size; $i++) { if ($records[$i]->[0] eq 'ban1') { my @a = @{$records[$i]}; &他のプログラムの処理(@a); if ($i + 2 < $size) { my $b = $records[$i+2]->[3]; &任意の行から読み取った値を処理($b); } } }

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

配列使ったら?

  • ORUKA1951
  • ベストアンサー率45% (5062/11036)
回答No.3

質問でされたいことが明白でないのですが・・。条件を後出しで追加しないで下さい。 CSVの先頭にkeywordを含む行を見つけて配列@aに入れて、配列の要素を参照するのでしたら$a[0]でよい事は前回説明しました。  ところが補足では複数行になっています。複数行の場合は、配列の配列になりますから、 my(@A, @tmp);   while (<>) {     @tmp = ********** と配列に代入     push @A, [ @tmp ]; } として、外から $A[2][3] になります。 このあたりは、基本的な処理になりますので、「プログラミングPerl」などの書籍を求められて、学ばれるほうが良いですよ。  Perlですから、様々な方法が取れます。--長所でもあり欠点

1988rands
質問者

補足

ORUKA1951様 ご回答いただきありがとうございます。 条件につきましては申し訳ございませんでした。 複数行の場合、配列の配列に入れることが 必要だという事は大変参考になりました。 書籍を購入し勉強しようと思います。 未熟な私に助言をいただき、誠にありがとうございました。 下記の方法で値を取得することができました。 ただ、こちらの方法だと、項目が増えるのに従い、 追記の作業も増えそうなので、 もう少しスマートな方法で値を取得・代入できないものでしょうか? よろしくお願いいたします。 open(IN,"data.csv") or die; my @data=<IN>; close(IN); $num=@data; foreach(@data) {($m1,$m2,$m3,$m4,$m5)=split(/,/,); push(@data0,"$m1"); push(@data1,"$m2"); push(@data2,"$m3"); push(@data3,"$m4"); push(@data4,"$m5"); $mname1 = @data4[1]; $mname2 = @data4[2]; $mname3 = @data4[3]; chomp($mname1); chomp($mname2); chomp($mname3); $mname1 =~ s/[\n\r]//g; $mname2 =~ s/[\n\r]//g; $mname3 =~ s/[\n\r]//g; }

  • ORUKA1951
  • ベストアンサー率45% (5062/11036)
回答No.2

>下記、参考サイトなどを見ながら、  splitを使っているだけであまり参考にならないようですね。 if($a1 == $ban1){} といきなり現れても$a1も、その値も未知 要は、行の先頭がban1の時に、各値を代入すればよい。 なお、csvはそれを作成したアプリケーション依存です。例えば各項の値に,が値として含まれていたときの処理などを加えなければなりません。(split(/,/,$_);は使えない)  excelの場合、値に,や"や改行が含まれている場合は値が""で括られます。  値にがある場合は""に置き換えられています。  それを取り出した後、,や""は再びもとの形に戻さなければなりません。  もう一点、値に改行が含まれていると困りますので 下記参考に! タブは  に置換してあるので戻す。 my $check = 'ban1'; while (my $line = <FH>) {   $line .= <FH> while ($line =~ tr/"// % 2 and !eof(FH));   if($line =~ /^$check,/ ){     $line =~ s/(?:\x0D\x0A|[\x0D\x0A])?$/,/;    my @a = map {/^"(.*)"$/s ? scalar($_ = $1, s/""/"/g, $_) : $_}($line =~ /("[^"]*(?:""[^"]*)*"|[^,]*),/g); # $a[0]~ いくつでも参照できるのでそれを使う。 }

1988rands
質問者

お礼

ORUKA1951様 ご回答いただきありがとうございます。 エクセルでのデータの扱いも、 処理の中に考慮する必要があるのですね。 とても勉強になりました。 ご教示いただいた内容で、試してみます。 ありがとうございました。

1988rands
質問者

補足

ORUKA1951様 お世話になっております。 先ほどはご回答ありがとうございました。 my $check = 'ban1';での該当した行を取得していますが、 任意の行、たとえば3行目の4列目を取得することは可能なのでしょうか? $a[2][3]で試しましたが、エラーが出てしましました。 何か追加すべき必要な処理がございましたら、 ご教授いただければありがたいです。 よろしくお願いいたします。

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

とりあえず ・「$a1」とは何か ・「該当の一行」とはどこか ・「他のプログラム」とは何か が分からない. 配列じゃダメなの?

1988rands
質問者

補足

Tacosan様 わかりにくい質問で申し訳ございませんでした。 質問内容の補足をいたします。 >・「$a1」とは何か こちらは参照するcsvファイルの1行にある列のことです。 a1が1行目、1番の列の項目で、1行に列は11項目あります。 1行目の11項目を分割して、 a1から、$a11の変数に代入できればと思っています。 >・「該当の一行」とはどこか こちらはif($a1 == $ban1)のことで、 1行目の一番目の項目が$ban1とマッチした行になります。 >・「他のプログラム」とは何か csvファイルを開いた後に、 a1 b1 等の各行頭の値を、プルダウンフォームに入れてみようと思っています。 以上、よろしくお願いいたします。

関連するQ&A

  • 新しいログの書き込み

    新しいログを追加で上に書き込む方法はどのようにしたらよいのかアイディアがありません。 ご教授願います。 if($mode eq "html"){ flock(FH, LOCK_EX); open(FH,"${datafile}"); @html = <FH>; close(FH); flock(FH, LOCK_NB); $html = join('',@html); @html = split(/$chtml/ , $html); $html[1] = $data; $html = join($chtml,@html); flock(FH, LOCK_EX); open(FH,">$datafile"); print FH $html; close(FH); flock(FH, LOCK_NB);

  • CSVデータの項目名からファイル名を付ける

    CSVデータからHTML拡張子で書きだすCGIを作成してます。 参考になるサブルーチンをネットで見つけたのですが、行の上から順に001.html・・・・のファイル名になり、CSVデータの項目にあるデータでファイル名を付けたいと思いますが、どのように処理したらよいかわかりません。アドバイス願います。 -------------------------------------------------------------- サンプルのCSVデータ(2行目のファイル名をファイル名につけたいです。) タイトル,ファイル名,会社名,担当者,URL 山ちゃん,yamadaya,山田屋,山田,http://www.oooxxx.oo 最上ちゃん,mogami,最上商店,最上,http://www.oooxxx.oo 南ちゃん,minami,南喫茶,南,http://www.oooxxx.oo -------------------------------------------------------------- コード: $list = join('',@csv); @list = split(/\n/, $list); for($count=1;$count<@list;$count++){ $html = $template; $filename = sprintf("%03d.html",$count); @listinfo = split(/\,/,$list[$count]); for($cnt=0;$cnt<@listinfo;$cnt++){ $no = sprintf("<!--%02d-->",$cnt); $html =~ s/$no/$listinfo[${cnt}]/g; } flock(FH, LOCK_EX); open(FH,">$filename"); print FH $html; close(FH); flock(FH, LOCK_NB); }

  • ファイルの読み書きについて教えてください。

    フォームから投稿されてきた内容を、テキストファイルに書き込むphpを作っているのですが、 flock関数で、誰かが書き込んでいるときに他の人が書き込めないようにファイルをロックしたいと思っています。 以下のソースでLOCK_EXとLOCK_UNは正しく動作するでしょうか。 いまいち不安で困っています。 //ポストされてきた内容が$nameに入ります $name = $_POST['name']; $fh=fopen("test.txt","a+"); flock($fh, LOCK_EX); fwrite($fh,"$name \n"); flock($fh, LOCK_UN); fclose($fh); どなたか詳しい方教えてください。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • csvの特定キーワード抽出後、その前後のキーワードを表示するには

    csvの特定キーワード抽出後、その前後のキーワードを表示するには -----sample.csv f01,名前01,説明01 d03,名前02,説明02 y12,名前03,説明03 -----呼び出しhtml sample.php?key=d03 -----sample.phpの処理 <?php $file_name = "sample.csv"; $file = @fopen($file_name, "r") or die("Data File Open Error"); flock($file, LOCK_SH); while (!feof($file)) { $buf = fgets($file, 4096) ; $data = split(",", $buf) ; if ($data[0] == $_GET["key"]) { $sampleid = $data[0] ; $samplename = $data[1] ; $sampleexp = $data[2] ; } } flock($file, LOCK_UN); fclose($file) ; ?> <h1><?php echo $samplename ?></h1> <h2><?php echo $sampleid ?></h2> <p><?php echo $sampleexp ?></p> 上記のようなフローの時に、sample.csv内の前後のデータをsample.php内で呼び出したいのですが、どうコードを書けばいいのかご教示ください。↓ <a href="ひとつ前のデータ">ひとつ前のデータ</a> <a href="ひとつ後のデータ">ひとつ後のデータ</a>

    • ベストアンサー
    • PHP
  • CSVファイルの上書き

    CSVファイルを$line[0] = $nowの時、上書きするということをしたいのですが、array_spliceでうまくいきません。 アドバイスお願いします。 $fp = fopen('log/order.csv', 'a+'); flock($fp,LOCK_EX); if ($fp) { require_once( "./common.php" ); $AddressData = LoadTextFile( "./log/order.csv", "SJIS", "SJIS" ); if ( $AddressData == false ) { exit; } else { for ( $i = 0; $i < sizeof( $AddressData ); $i++ ) { $line = explode( ",", $AddressData[ $i ] ); if($line[0] = $now){ array_splice($line, 1, 3, array("1","2","3")); #fputs($fp, $buf2); flock($fp,LOCK_UN); fclose($fp); } } } }

    • 締切済み
    • PHP
  • エクセルで編集したCSVファイルを読み込むときに

    よろしくお願い致します。 エクセルで編集したCSVファイルを読み込み、HTMLとして表示するCGIがあります。 エクセルでCSVファイルを編集すると最後の項目の後にカンマ(,)が付かないのですが、 使用しているCGIでは、カンマがないと行が改行されたとみなされません。 行の最後にカンマがなくても行を改行させるには、どのようなコードを追加すればよいのでしょうか? CGIのCSVファイルの読み込みする部分のコードは以下のようになっています。 # ログファイル読み込み my $LOG_FILE = 'log.csv'; my $io = IO::File->new($LOG_FILE, 'r') or die $!; flock($io, 1); while(my $line = $io->getline) { push @ids, (split(/,/, $line))[0]; push @new_checks, (split(/,/, $line))[1]; push @dates, (split(/,/, $line))[2]; push @contents, (split(/,/, $line))[3]; push @contents2, (split(/,/, $line))[4]; push @contents3, (split(/,/, $line))[5]; push @contents4, (split(/,/, $line))[6]; push @contents5, (split(/,/, $line))[7]; push @contents6, (split(/,/, $line))[8]; } 分かりにくい説明で申し訳ありません。 補足説明も致しますので、どうぞよろしくお願い致します。

    • ベストアンサー
    • CGI
  • TSVデータを上書きしたい

    はじめまして。 CGI初心者です。 データの上書きがしたいのですがなかなかうまくいかなくてこまっています。 以下のソースは追加書き込み処理には成功しています。 以下に何を施せば上書きがうまくいくのかアドバイスをお願いします。 $scheduleFile2 = qq($form{"mon"}.tsv); # 読み込み処理 open(LOG,"$scheduleDir/$scheduleFile2"); @logs = <LOG>; close(LOG); foreach $logs(@logs){ ($golfdate,$areada,$ken,$date2,$para)=split(/\t/,$logs); } # 読み込み処理 # 書き込み処理 unless(&serchFile($scheduleDir,$scheduleFile2)){ &makeFile("$scheduleDir/$scheduleFile2"); } @DATA = (); open(FH,"+<$scheduleDir/$scheduleFile2"); flock(FH,LOCK_EX); while(<FH>){ $_ =~ s/\r//g; $_ =~ s/\n//g; # 行の末を削除する chomp; push(@DATA,$_); } $data01 = $form{"code"}.$form{"date"}; $data2 = $form{"area"}; $data3 = $form{"prefecture"}; $data4 = $form{"date"}; $data5 = $form{"open_state"}."\n"; $data = qq($data01\t$data2\t$data3\t$data4\t$data5); print FH "$data"; flock(FH,8); close(FH);

    • 締切済み
    • CGI
  • 2次元配列の扱い

    2次元配列のようなものについてどなたかご教授ください。 たとえば 1,2,3,4 a,b,c,d という2行のテキストデータを読み込んで (["1","2","3","4"], ["a","b","c","d"]) のようようなリストにはできたみたいなんですが それをまたもとのカンマ区切りテキストにできなくて困ってます。 どこが間違ってるのでしょうか。よろしくお願いします。 open(READ,$filename) || &error("Read Error"); @BASE = <READ>; close(READ); @itemlist=(); foreach $num (0 .. $#BASE) { $BASE[$num] =~ s/\n//g; (@item) = split(/\,/,$BASE[$num]); @itemlist = (@itemlist,[@item]); } ####### $dummy=""; foreach $num (0 .. $#itemlist) { $renketu=join(",",$itemlist[$num]) ."\n"; $dummy.=$renketu; } open(WRITE,">$filename"); flock(WRITE,2); print WRITE $dummy; close(WRITE);

    • ベストアンサー
    • Perl
  • if文中で@***(配列変数)って・・・。

    if文中で配列変数って使用できるのでしょうか? やりたいことは、 フォームを使って入力されたデータと、ログファイルの中身を1行ずつ比べて、 同じものがあったら、そこで比較を終了させる、というようなことをやりたいのです。 たとえでこんな感じでif文つくりました。(これもあってるかどうか微妙なのですが。) for($i=0; $i<5){ @FILELOG2 = split(/&/,$FILELOG[$i]); if (@FILELOG2 eq @log){ print "ok\n"; }else{ print "ng\n"; } exit; } フォームを使って入力されたデータは、 read(STDIN,$buffer,$ENV{'content_length'}); $buffer =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; @log =split(/&/,$buffer); のような感じで処理してあります。 ログファイルは #ログファイルをオープン。 open FILE,"<02.log"; flock(FILE,2); @FILELOG=<FILE>; flock(FILE,8); close FILE; のようにしてあります。 おわかりの方、よろしくお願いします。

    • ベストアンサー
    • CGI
  • ファイルへの書き込み

    フォームに入力されたデータをCSVファイルに書き込みたいのですが、以下のようにすると追加で書き込みはできるのですが、ずっと改行されずに1行に書き込まれてしまうので、新しいデータを入れる際に改行されるようにしたいのですが、どのようにすればいいでしょうか? $fp = fopen(TEST_FILE,"a") or die("ファイルを開けません\n"); flock($fp, LOCK_EX); fputs($fp, "aaa")."\n"; flock($fp, LOCK_UN); fclose($fp);

    • ベストアンサー
    • PHP