- ベストアンサー
grepコマンドの使用方法について
- 配列の中で今日の日付と一致するものを表示するためにgrepコマンドを使用していますが、正しく動作していないようです。
- コマンドプロンプトでは動作するが、スクリプト内ではうまく動作しない原因がわかりません。
- 正しい使用方法や問題点をご存知の方はご教示ください。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
> これもコマンドプロンプトは通るのですが・・・ についてですが、エラーは起きていない、という意味だったんですね。 てっきりプロンプトでは正常に動作しているのかと思ってました^^; 質問の grep の部分は、書式としては間違っていないのでエラーなどは出ませんが、プログラムの意図からすると間違っていますので、やはりNo.1のように修正する必要があります。 それと、 > 「今日」も、「今日」と異なるデータもすべて出力されません。 ということですが、@record にデータが入っていて、gettoday() も正常値を返し、しかも質問のような grep の使い方であれば、間違いなく @result = @record となるはずです。 怪しい箇所を全てブロックしたスクリプトを書いてみましたので、一度これをお試しください。 use strict; chomp(my @record = <DATA>); my @result = grep($_ eq &gettoday(), @record); print "gettoday() is\n"; print "\t", &gettoday(), "\n"; print "\@record is\n"; print "\t$_\n" for @record; print "\@result is\n"; print "\t$_\n" for @result; exit; sub gettoday { '2002/12/9(月)' } __DATA__ 2002/12/8(日) 2002/12/9(月) 2002/12/10(火) これの結果は、次のようになります。 gettoday() is 2002/12/9(月) @record is 2002/12/8(日) 2002/12/9(月) 2002/12/10(火) @result is 2002/12/9(月) これがうまく行ったら sub gettoday {・・・} の行を削除し、use strict; の下に require 'sub_today.pl'; を入れて試してみてください。 それでもうまく行くなら DATA を IN に変更して open( IN, "../days.txt" ) or die 'Not found'; と close( IN ); を、chomp(・・・); を挟むように入れて試してみてください。 (ここまでくれば、ほとんど元のプログラムと同じ状態です。) どこかでうまく行かなくなったら、その状態を補足してください。
その他の回答 (3)
- a-kuma
- ベストアンサー率50% (1122/2211)
> grepのところがうまくいってないようなのですが、コマンドプロンプトでは通ってしまい、何がミスなのかよくわかりません。 読み込むファイルのパスが相対パスで書かれていますが、CGI が動作するときのカレントディレクトリは分かってますか? とりあえず、ファイル名をフルパスで書いてみたら?
- leaz024
- ベストアンサー率75% (398/526)
問題がありそうなところをいくつか。 まず、ファイルから読み込んだデータをそのまま使ってますよね。 ファイルから読み込んだデータには「改行」がくっついているので、それを取らないといけません。 ファイル読み込み部を chomp(@record = <IN>); としてください。 また、ファイルの内容はちゃんと読めてますか? grep かける前のデータは表示できますか? 相対パスでファイルを開いているので、カレントディレクトリが違ってしまうとファイルは開けません。 open にエラーチェックがないので、その辺でミスっていることも考えられます。 あと、 > これもコマンドプロンプトは通るのですが・・・ これって、「今日」と異なるデータは出力されないってことですか? 質問の方法だと EXPR が常に真となってしまうので、LIST が筒抜けになってしまいそうな気がするんですが・・・ (手元で試した感じでもそうでした。)
補足
チェックありがとうございます。 openエラー個所は記述を省略してしまってます。すみません。 >また、ファイルの内容はちゃんと読めてますか? >grep かける前のデータは表示できますか? print @result; を下記内容に変更してみて確認済みです。 print &gettoday(); →正しく表示されます。 print @record[n]; →正しく表示されます。※nの数字をいろいろ変更してみました。 >これって、「今日」と異なるデータは出力されないってことですか? 「今日」も、「今日」と異なるデータもすべて出力されません。 意図的には一致した今日のデータを表示するつもりだったのですが・・・ とりあえず、逆の条件(今日以外じゃなかったら表示する)で試してみます。
- leaz024
- ベストアンサー率75% (398/526)
grepの書式は grep EXPR, LIST となっており、EXPR には「条件式」を指定します。 foreach のように LIST 内の値を1つずつ $_ に入れ、EXPR を評価して真になったもののリストを返します。 多分、 @result = grep(&gettoday eq $_, @record); のようにすればOKだと思いますよ。
補足
う~ん。 これもコマンドプロンプトは通るのですが・・・ prit行が何も表示されないです。 元のデータが悪いのかな?ちなみに &gettoday(本日の日付):2002/12/9(月) @record(1行ずつ):2002/12/1(日)~2002/12/31(火) です。
お礼
返事が遅くなりましたが、上記方法を確認し疑問が解決しました。 ありがとうございました。
補足
再びお返事ありがとうございます。 ご返事いただいた内容はまだ試してないのですが、 この方法での解決が行き詰まったので別の方法で解決させました。 txtファイルをcsvに変更して(当然「2002/12/11,(水)」と加工して) /////////////////////////////////// $num = 0; foreach(@record){ ($days[$num],$week[$num]) = split(/\,/,$_); $monthdays[$num] = $days[$num].$week[$num] ; $check = index($days[$num], &gettoday()); if ( $check == 0 ){ $out = $num ; } $num++; } $days1 = $monthdays[$out] ; $days2 = $monthdays[$out+1] ; $days3 = $monthdays[$out+2] ; ・ ・ ・ /////////////////////////////////// 目的は達成したのですが、個人的に気になるので grepの方法が解決してからこの質問を締めたいと思います。 ・・・ので、確認するまでしばらくお待ちください。よろしくお願いします。