- ベストアンサー
Perl初心者の質問:CSVから値を割り出す方法は?
- Perl初心者がCSVファイルから値を割り出す方法について教えてください。
- また、CSVファイルの一番右の列を指定すると値が割り出せない現象が起きます。この解消方法も教えてください。
- さらに、Open関数でdieが発生した場合にログに出力する共通関数の作成方法も教えてください。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
#4>実行ログなんかもとりたいのですが、そういった場合の書き込む頻度が高い場合でも必要ないですか? 1つのプログラム(バッチ処理)からなら、要らないと思います。 #4>複数のCSVファイルを一気に読ませたいんです。 要はこれを何度も処理させることを、このスクリプト上で出来ませんでしょうか? 処理の流れがどういう具合なのかよくわからないので、なんとも言えないですが、トップの部分でCSVファイル毎ループしてやればいいような気がします。 #4>↑場合、簡略化して書く方法ってありますか? 例えば、 prog.pl data.csv para1 para2 para3 para4 とかの場合 $filename = shift; func(@ARGV); #para1,para2,para3,para4 が渡される。 でいいと思います。 そういうことでないなら、$para1,$para2,$para3,$para4 のように個別に名前を付け直すより、配列のまま使うのがいいと思います。(配列でコピーするとか)
その他の回答 (4)
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
#3>自己解決しました。 それは、良かったですね^^ #3>大丈夫です。 なら別に良いです。 die じゃなくて、単にexit を使って終了すればいいかもしれませんね。 #3>書き込む場合はロック処理をしたほうがいいのはわかるんですが、読み込むときにも設置したほうがいいのですか? CSVデータの話ですよね。 読み込んだデータを変更して書き込む処理をしない場合(つまり、読み出ししかしない場合) 必要ないと思います。 書き込む場合も、バッチ処理で、そのプログラムしか書き込みしないような場合特別必要ないと思います。 #3>メイン処理のOpenとcloseを繰り返して、負荷をかけた状態のパフォーマンスをみたいんですが、どうするのが効率的ですか?? もう一つイメージがわかないんですけど、 UNIXを使っていてshell から全体のパフォーマンスをみるには、 time コマンドを使えばいいと思います。 perl 内部で実行時間を計るには、単純に、 time関数で時間を計る(秒単位)か、それで精度が足りない場合 Time::HiRes モジュール(CPAN)を使うとか あと、Benchmark モジュール(標準モジュール)を使うとか すればいいんじゃないかと思います。
補足
BLUEPIXY様、夜分にお返事ありがとうございます。 >die じゃなくて、単にexit を使って終了すればいいかもしれませんね。 dieとexitは動きが変わるんですか? ちなみにスカラ変数にメッセージをセットして、ログ関数の引数に変数を与えたら 「Died at スクリプト名」 が出力されてしまうんですね。。。 >読み込んだデータを変更して書き込む処理をしない場合 実行ログなんかもとりたいのですが、そういった場合の書き込む頻度が高い場合でも 必要ないですか? >もう一つイメージがわかないんですけど、 複数のCSVファイルを一気に読ませたいんです。 このスクリプト自体がサブルーチンだということは前に、ご説明したかと思いますが、 要はこれを何度も処理させることを、このスクリプト上で出来ませんでしょうか? それから $para1 = $ARGV[0]; $para2 = $ARGV[1]; $para3 = $ARGV[2]; $para4 = $ARGV[3]; $para5 = $ARGV[4]; ・ ・ 場合、簡略化して書く方法ってありますか? スミマセン、いつも質問攻めばかりでm(__)m
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
#2>下記のデータがどうしても、読めません。 読めないという状況をもう少し詳しく教えてください。 CSVデータが取り込めないということなのか、 関数がerr! を返すということなのか とか うまく行かない場合のパラメータも教えてください。 あと、 #2>ログ処理もバッチリです。 関数からdie を呼び出すようにすると、表示されるエラー行が、関数のdie を呼び出した行になりますが、それは、問題ないのでしょうか? なお、今日は、不在にするので、返事は遅くなるかも知れません。
補足
BLUEPIXY様、補足要求ありがとうございます。 大変スミマセン、自己解決しました。 何故エラー(err!)になってかというと、@ARVG[0]~[5]までしかスカラ変数に設定して いなかった為、パラメータが増えると読めてなかったみたいです。ゴメンナサイ。。。 ログ関数は、引数に渡されたMSG自体が書き込まれるという仕様ですよね。例えば変数に メッセージを仕込んでおいて、ログ関数の使用箇所によって変数を切り分ければいいわけですよね? 大丈夫です。ありがとうございます。 ところで迷惑ついでに、教えて頂きたいのですが、書き込む場合はロック処理 をしたほうがいいのはわかるんですが、読み込むときにも設置したほうがいいのですか? それと、メイン処理のOpenとcloseを繰り返して、負荷をかけた状態のパフォーマンスを みたいんですが、どうするのが効率的ですか?? print文にループかけただけでは、意味ないですよね。。。 度々、お力をお借りしてしまって申し訳ありませんが、よろしくお願いいたします。
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
すみません、#1ですが、ボケてました print squeezed(1,1,1,1,1);#XX は、最左列ですね。orz print squeezed(4,1,1,3,4);#YO とした時YO が得られないということですね。 さっき確認しました。 元のソースで CSVデータを読み込んでいるところで while(<IN>){ chomp; #この行を追加 のようにして下さい。 要するに、 最後のデータには、改行コードがついていたのでマッチしなかったということです。 chomp は、末尾に改行がある時それを削除する命令です。 すみませんでした。
補足
BLUEPIXY様、返事が遅くなりました。 いつも私の他力本願なお願いにお付き合い頂いて感謝しております。 chompの追記ならびに、ログ処理もバッチリです。 本当にありがとうございます。 ところで、ひとつ問題が起きてしまいましたので、またお聞かせください。 下記のデータがどうしても、読めません。ベースにしていたCSVに 1行加えただけなのですが… 読めてるデータの行を追加したりすると、読めなくなるパターンがあります。何故なのでしょう? 1,1,1,1,2,2,2,2,3,3,3,3 1,2,3,4,1,2,3,4,1,2,3,4 1:4,1:4,1:4,1:4,1:5,1:5,1:5,1:5,1:6,1:6,1:6,1:6 1:5,1:5,1:5,1:5,1:6,1:6,1:6,1:6,1:7,1:7,1:7,1:7 "1,3",2,4,1,"2,4",3,1,1,4,"2,3","2,3",1 1,2,3,4,1,2,3,4,1,2,3,4 TO,TO,TO,TO,WH,WH,WH,WH,LE,LE,LE,LE ちなみに私の環境では、@ARGVでパラメータを直打ち(ファイル名含め)で渡しているの ですが、これで動きが変わったりはしないですよね? お願いします。
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
>一番右の縦列をパラメータに指定すると何故だか値が割出せません。 うまくいかなくてすみません・ ですが 当方で試してみたところでは print squeezed(1,1,1,1,1); では、期待通り "XX" が返されます。 何か、質問者と当方で、扱っているデータが違うのではないかと思います。 先の質問で挙げられているデータと異なる場合、 データと試してみたパラメータを補足していただけますか? >Open関数にて「die」が選択されたときにlogに出力するというのをサブルーチンで、共通関数みたいな形にしたいのですがどうすればいいのでしょう? open(IN, "file") || die "ファイルのオープンに失敗しました"; みたいな話ですよね die が選択された時というより、 open が失敗した時 || 以降の命令が実行されるので、 open(IN, "file") || &myLogOut("file open error!"); みたいに置き換えて sub myLogOut { my $msg = shift; open(LOG, ">>err.log"); print LOG "$msg\n"; close(LOG); die $msg; } みたいな感じにすればいいと思います。
お礼
BLUEPIXY様、 お世話になってます。 長きに渡り、なにからなにまで感謝の気持ちでいっぱいです。 別件でお邪魔することもあると思いますが、そのときはまた 宜しくお願いいたします。 本当にありがとうございました^^