• ベストアンサー

CSVファイルをperlプログラムで処理する場合

すみません、度々perl初心者のものです。 CSVファイルを1行ずつ読み込んで処理をしたい場合、 1項目内のデータの中に改行がある場合、 どのような方法で対処出来るでしょうか? 例えば "aaa,bbb,ccc ddd,eee,fff" 上記のようにcccとdddの間に改行が入ってるため 本当は1レコードのはずなのに2レコードとして 処理を行ってしまう。 perlで何かやり方はあるのでしょうか? csvを加工するのもよいのですが、データが多量に あるため、プログラム上でなんとかしたいと思うのですが。。。 すみません、宜しくお願い致します。

  • rariko
  • お礼率28% (223/790)
  • Perl
  • 回答数5
  • ありがとう数1

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

  • ベストアンサー
  • rafysta
  • ベストアンサー率45% (24/53)
回答No.3

自分でしたら、まず、ダブルクォテーションで囲まれている改行コードを、すべて何かの文字に置換してしまいます。その後は、普通のCSVと同様に処理をして、最後に置換した文字を改行コードに戻してやります。 my $file = 'data.csv'; open IN, '<', $file or die "cannot open $file : $!"; $/ = ""; my $data = <IN>; close IN; while($data =~ s/\"(.+)\n(.+)\"/$1<>$2/g){ } # 後は普通のCSVとして処理(例) foreach(split /\n/, $data){ my @data = split /,/; map{ s/<>/\n/g } @data; print "@data\n"; }

その他の回答 (4)

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

$/ を undef にして全部読み込んでから /"(.*?)"/m するとか?

  • rafysta
  • ベストアンサー率45% (24/53)
回答No.4

# No.3の訂正 while($data =~ s/\"(.+)\n(.+)\"/$1<>$2/g){ } じゃなくて while($data =~ s/\"(.+)\n(.+)\"/"$1<>$2"/g){ }

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

安易な方法で、必要なパターンを満たしているか自信がないですが、こんな感じでどうでしょう。 ---------------------------------------------------------------- use encoding "Shift_JIS"; sub readCSVline($){ my $FH = shift ; my $line = ""; my $count=0; while(<$FH>){ $count += tr/\"/\"/;#" の数を数える $line .= $_; #条件が成立するまで、行を拡張する if($count % 2 == 0){ #偶数倍になっていたらマッチングしているとして読み込んだ行を返す return $line; } } } open(IN, "<data.csv"); while($line = readCSVline(IN)){ #一行の処理 } close(IN);

  • galluda
  • ベストアンサー率35% (440/1242)
回答No.1

がると申します。 ちと面倒な処理にはなるのですが。状態遷移プログラムが書けるのであれば(Perlで十分に記述は可能です)、処理は出来るかと。…いやまぁ状態遷移じゃなくても書けるのですが、状態遷移のほうが楽なので、程度なのですが。 googleあたりで「CSV 状態遷移」とかで調べたりすると色々と情報など出てくるかと思います。

関連するQ&A

  • VBAでCSV内にある改行を取る方法

    あるシステムが吐くcsvファイルの項目の中に改行が入っているものがあります。 例) 01,aaa,bbb(改行)bbb,ccc(改行) 02,ddd,eee,fff(改行) 03,ggg(改行)ggg,hhh,iii(改行) このCSVファイルをエクセルのマクロで読み込んでシートに展開したい のですが、項目中にある改行で別レコードを認識してしまいます。 結果) A B C D ---+---+---+--- 01 aaa bbb  bbb ccc 02 ddd eee fff 03 ggg ggg hhh iii これを以下のようにしたいのですが・・・ A B C D ---+------+------+---- 01 aaa bbbbbb ccc 02 ddd eee fff 03 gggggg hhh iii どうやればよいでしょうか? ご教授お願いいたします。

  • CSVファイルをAccessに取りこみたい

    以下のような2つのCSVファイルがあるとします。 【hoge1.csv】 aaa,bbb,ccc,ddd 1,2,3,4 【hoge2.csv】 aaa,bbb,ddd,eee,fff 1,2,4,5,6 Accessをあまり使用したことがないので教えていただきたいのですが、 hoge1.csv、hoge2.csvを、以下のような形で Accessの1つのテーブルにインポートする事はできるのでしょうか? ---------------------------- | aaa | bbb | ccc | ddd | eee | fff | | 1 | 2 | 3 | 4 |  |  | | 1 | 2 |  | 4 | 5 | 6 | ---------------------------- ※「aaa」「bbb」…をフィールド名としたいです vb等でプログラムを自作するしかないのでしょうか? 何か良い方法がありましたら教えてください。お願いします。

  • CSVデータをツリー表示させたい

    業務で、WEBサイトにCSVデータを表示させたいと考えています。 CSVデータは、毎日更新されるもので、行数も日々変更されます。 項目の中に「レベル」という項目があり、この「レベル」の値を使って、 ツリー表示出来ないかと考えています。 希望としては、決められたフォルダに決められたファイル名で、 CSVデータを置けば、自動的にWEB上にツリー表示されるという ことです。 J-query等で、これを実現出来るプラグインが無いか探しているのですが、 なかなか希望に合うものが見つからず、困っています。 (CSVをWEB表示するものは見つかるのですが、ツリー表示出来る ものが見つかりません) 何か、良い方法があれば、ご教示頂けませんでしょうか? 例 コード  レベル 品名  規格 ・・・・    コード     レベル 品名  規格 ・・・・  1234    1   AAA   aaa       -1234       1    AAA   aaa 2345    2   BBB   bbb        ∟2345     2    BBB  bbb 3456    3   CCC   ccc          ∟3456   3    CCC  ccc 4567    3   DDD   ddd          ∟4567   3    DDD  ddd 5678    3   EEE   eee           ∟5678   3    EEE  eee 6789    4   FFF   fff             ∟6789  4    FFF   fff 7890    3   GGG  ggg           ∟7890   3    GGG  ggg

  • Perlの正規表現について

    Perlの正規表現について質問です. ■質問 aaa bbb aaa bbb ccc "ddd" aaa bbb ccc "ddd eee" aaa bbb ccc ddd eee "fff ggg hhh iii" というような,文字列が書かれているファイルがあるとします. ※ダブルクォーテーションが無い行もあります. ※ダブルクォーテーション内のスペースの数は,行によってそれぞれ異なります. これを,ダブルクォーテーションの中にあるスペースだけ アンダーバーに置換する場合の正規表現を教えて下さい. つまり,下記の出力にしたいです. aaa bbb aaa bbb ccc "ddd" aaa bbb ccc "ddd_eee" aaa bbb ccc ddd eee "fff_ggg_hhh_iii" ■条件 ※ちょっと古いPerlでも動くよう,ゼロ幅肯定/否定後読((?<),(!<))は使わないでください. ※単に実現するだけなら, # cat inputfile | print -pe 'sub f(){}(shift;s/ /_/;return $_;); s/(\".*\")/&f($1)/e;' みたいな感じで置換できそうですが,「正規表現だけで簡単に書けるかどうか」が知りたいのです(正規表現だけで実現出来る場合,そのアルゴリズムを知りたいです).そのため,関数と/eオプションは使わないでください.

    • ベストアンサー
    • Perl
  • CSVに外部テキストファイルを列として追加する方法

    こんにちは。 CSVファイル(base.csv)の先頭列に、別のテキストファイル(add.txt)の中身を新規の列として挿入したいと考えているのですが、よい方法がわかりません。。。 どうのような方法を使えば対応することができるでしょうか? どうぞよろしくお願いいたします。 ■CSVファイル(master.csv) title,developer_name,seller_name,primary_genre_name,application_url AAA,BBB,CCC,DDD,EEE AAA,BBB,CCC,DDD,EEE AAA,BBB,CCC,DDD,EEE AAA,BBB,CCC,DDD,EEE ■テキストファイル(add.txt) id 000 111 222 333 ↓ ■目標としたファイル(master.csv) id,title,developer_name,seller_name,primary_genre_name,application_url 000,AAA,BBB,CCC,DDD,EEE 111,AAA,BBB,CCC,DDD,EEE 222,AAA,BBB,CCC,DDD,EEE 333,AAA,BBB,CCC,DDD,EEE

  • Excelの関数に詳しい方、お願いします。

    わかりづらい説明かもしれませんが、よろしくお願いします。 例として、 AAA*BBB*CCC*DDD*EEE*FFF AAA*BBB*CCC*DDD*EEE*FFF AAA*BBB*CCC*DDD*EEE*FFF AAA*BBB*CCC*DDD*EEE*FFF AAA*BBB*CCC*DDD*EEE*FFF ・ ・ ・ といった文字列がエクセルの先頭列A1~A100までずらりと並んでいるとします。 各アルファベットには任意の数字(日付など)が入るとして、この並んだ百件のデータからCCCの部分の最大値を表示するための適切な関数があれば教えていただけないでしょうか? 現在少々急いでいるため言葉足らずで申し訳ありませんが、よろしくお願いいたします.

  • テキスト処理のシェルプログラム

    UNIXシェルもしくはPerlでテキスト処理のシェルスクリプト を作成したいのですがご教授お願いします 1000行あるテキストファイルを 2行単位で区切り2行単位で横一列へ置換しテキストへ出力したいのですが 例 処理前 aaa bbb ccc ddd eee fff 処理後 aaa,ccc,eee bbb,ddd,fff ご教授よろしくお願いします

  • C言語による「テキストファイルの読み書き(fprintf)」について

    C言語による「テキストファイルの読み書き(fprintf)」について質問です ずぶの初心者ですが、既知のファイルの1行目に指定した文字列を付加させるプログラムを作りたいと思っています。 以下のように作りました。 ------------------------------------------------------------ #include <stdio.h> int main(void) { FILE *fp; fp = fopen("test.csv","r+"); fprintf(fp,"コントロールカラム1,コントロールカラム2,・・・(略)・・・,コントロールカラム56\n"); fclose(fp); return 0; } ------------------------------------------------------------ このとき「test.csv」の内容が以下のようであったとします。(容量は1MBくらいです。) 001,aaa,bbb,ccc,ddd,eee,fff,ggg,hhh,iii,jjj 002,aaa,bbb,ccc,ddd,eee,fff,ggg,hhh,iii,jjj ~(略) 5000,aaa,bbb,ccc,ddd,eee,fff,ggg,hhh,iii,jjj この状態でプログラムをコンパイルして実行すると、「test.csv」の内容が以下のようになってしまいます。(一行目が消える) AAA,BBB,CCC,DDD,EEE 002,aaa,bbb,ccc,ddd,eee,fff,ggg,hhh,iii,jjj ~(略) 5000,aaa,bbb,ccc,ddd,eee,fff,ggg,hhh,iii,jjj またcsvの行が増える度に妙な挙動になっていきます・・・(一行あいたり、先頭行が5行ほど消えたり) 希望する動作としては コントロールカラム1,コントロールカラム2,・・・(略)・・・,コントロールカラム56 001,aaa,bbb,ccc,ddd,eee,fff,ggg,hhh,iii,jjj 002,aaa,bbb,ccc,ddd,eee,fff,ggg,hhh,iii,jjj ~(略) 5000,aaa,bbb,ccc,ddd,eee,fff,ggg,hhh,iii,jjj のようになるようにしたいのですがどのようにすればよいのでしょうか。 よろしくお願いします。 (使用ソフト:Borland C++ Compiler, Cpad) 参考にしたサイトの項目:http://homepage3.nifty.com/mmgames/c_guide/17-01.html

  • perlでの正規表現について教えてください。

    たとえば、 $A = 'aaa/bbb/ccc/ddd/eee/fff/ggg' というものがあったときにperlの正規表現でddd/のすぐ後の部分を抜き取って違う変数に入れたいのですが、それを正規表現で切り取りたいのですが、どうしたらいいかわからないです。 初歩的な質問ですが、お答えいただければ幸いです。 よろしくお願いします。

  • VBAでCSVファイルを分割したい

    VBAを利用して、あるCSVファイルを一定のレコード数ごとに新しいファイルにファイル分割したいです。 やりたいことは、以下のようなイメージです。 関連サイトなどを参考に自分なりに取り組んでみましたが、なかなかうまくいきません。 VBAでなくても実現できそうですが、ここまでやったので勉強のためにもVBAでやりたいです。 サンプルコードなど教えていただけるとうれしいです。 ヒントでも結構ですので、よろしくおねがいします。 (2レコードずつ分割する例) sample.csv ヘッダ1,ヘッダ2,ヘッダ3,ヘッダ4 aaa@aa.aa,123,あいうえ,111-111 bbb@bb.bb,456,かきくけ,222-222 ccc@cc.cc,789,さしすせ,333-333 ddd@dd.dd,012,たちつて,444-444 eee@ee.ee,345,なにぬね,555-555 fff@ff.ff,678,たちつて,666-666 ↓↓↓ ☆sample_1.csv ヘッダ1,ヘッダ2,ヘッダ3,ヘッダ4   →各ファイルにヘッダも入れたいです。 aaa@aa.aa,123,あいうえ,111-111 bbb@bb.bb,456,かきくけ,222-222 ☆sample_2.csv ヘッダ1,ヘッダ2,ヘッダ3,ヘッダ4 ccc@cc.cc,789,さしすせ,333-333 ddd@dd.dd,012,たちつて,444-444 ☆sample_3.csv ヘッダ1,ヘッダ2,ヘッダ3,ヘッダ4 eee@ee.ee,345,なにぬね,555-555 fff@ff.ff,678,たちつて,666-666

専門家に質問してみよう