• 締切済み

phpで作成したファイルをシェルで読み込むと最後の行を読み込めない

phpでリストを取得し、ファイルに書き込んでいます。 リストはスペース区切りで帰ってくるので、改行コードに変換しています。 $str = "a b c"; $str =str_replace(" ","\n",$str); //リストファイルへ書き込み $pointer=fopen("aaa.txt","w"); flock($pointer, LOCK_EX); fputs($pointer, $str); flock($pointer, LOCK_UN); fclose($pointer); これをviで開いてみると a b c と予定通り書き込まれています。 このリストをシェルスクリプトでループして読み込んでいるのですが 最後の行を読み込んでくれません。 while read line do echo "$line" done < aaa.txt とやると 最後の行が読み込まれないんです!(aとbしか表示されない) ちなみに、aaa.txtをviで開いて何もせずに保存終了すると 正常に最後の行が表示されることから、aaa.txtの終了コードがうまく 書き込まれていないのでは?と予想していますが、よくわかっていません。 どうしたら最後の行を読んでくれるのでしょうか。 ※最後の行に改行コードをつけると次の空白行を読みにいってエラーになるのでそれ以外でお願いします。

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

みんなの回答

  • mpx
  • ベストアンサー率71% (149/209)
回答No.1

>> このリストをシェルスクリプトでループして読み込んでいるのですが >> 最後の行を読み込んでくれません。 read は、改行コードを見つけたら真、なければ 偽 ですので 最終行に改行がなければ ループを出てしまいます。 よって、下記を試してみてください while read line do echo "$line" done < aaa.txt echo "$line" >> aaa.txtをviで開いて何もせずに保存終了すると viは最終行に改行コードが無いと改行コードを補完して付け足すはずです。viでの保存前後でHD(ヘキサダンプ)して最終バイトを確認してみてください >> ※最後の行に改行コードをつけると次の空白行を読みにいってエラーになるのでそれ以外でお願いします 最後に改行コードを付け加えることを薦めます。 「次の空白行を読みにいってエラーになるので」そのエラーになる読み取りプログラムに問題がある気がします。

maruzou777
質問者

お礼

phpのバージョンは5.24なんですが、 phpのfputsで上記のように作成したファイルにはEOLがつかないようです。 (恐らくバグです。php6では修正されているようです) readは改行コード\nがあると次の行を読み込みにいって 次の行の頭からEOLまでを取り込む動きをしているようですので、 EOLがない行は取り込まれていませんでした。 ファイル書き込みの際に、 $pointer=fopen("aaa.txt","w"); flock($pointer, LOCK_EX); fputs($pointer, $str); fputs($pointer,PHP_EOL);  ←NEW! flock($pointer, LOCK_UN); fclose($pointer); とphp改行を入れたらなぜか最後が改行されずに、EOLが付与されて、 正常な動作をさせることができました。(これもナゾですが・・・) しかしこのやり方だとphpのバージョンをあげた場合不具合が出る可能性があるため、シェルのほうで1行 if [ $str ]; then を追加することで対応しました。 回答ありがとうございました。

関連するQ&A

  • ファイルの最後の行から表示させる(最新情報を5回分だけ表示)

    ファイルの最後に1行追加し、6行以上になるとファイルの先頭を1行削除。 表示は最後の行から行うスクリプトを作りたいのです。 新しい情報を5回分だけ表示する様にしたかったのですが、余りにも力技なのでもう少しスマートにやる方法を教えてもらえませんか? ----sort.txt---- 1a 2b 3c 4d ---------------- #!/usr/bin/perl $fname = "sort.txt"; print "Content-type: text/html;\n\n"; $aaa="5e"; open(OUT, ">>$fname"); flock(OUT, LOCK_EX); print OUT "$aaa\n"; flock(OUT, LOCK_NB); close(OUT); open(IN, "$fname"); $cnt = "0"; while($line = <IN>){ $a[$cnt] = "$line"; $cnt++; } close(IN); if($cnt > 5){ open(OUT, ">$fname"); flock(OUT, LOCK_EX); $cnt = "0"; while($cnt < 6){ if($cnt > 0){ print OUT "$a[$cnt]"; } $cnt++; } flock(OUT, LOCK_NB); close(OUT); } $cnt = "0"; open(OUT, "$fname"); @buff = <OUT>; close(OUT); foreach $line ( reverse @buff ){ $cnt++; print "$line<br>\n"; } exit();

    • ベストアンサー
    • Perl
  • 改行コードだけの行が現れるまでを1行として取得

    PHPでインプットファイルから、 改行コードだけの行が現れるまでを1行として取得しようと思っています。 下記例のように、 fgetsで行を取得しようとしたら、 改行が現れた時点までを1行としてしまうので、 少し違った1行の取得となってしまいました。 どうすればPHPで実現できるのか教えて欲しいです。 【例】 this is a pen. good-bye. ↓ this is a pen.good-bye. を1行分として取得したい。 # PHP 5.3.9 # CentOS 5.8 ---- $inputpath = '/home/test/test.txt'; $file = fopen($inputpath,"r") or die("open error $inputpath"); flock($file,LOCK_SH); while (!feof($file)){ $string = fgets($file,10000); print "$string"; print "\n"; } //relese the lock flock($file, LOCK_UN); //close the file fclose($file); ----

    • ベストアンサー
    • PHP
  • PHPのファイル書き込み、呼び出しにおいて

    PHP初心者です。 最初にscore.txtから配列score[]に値を代入し、その後FORMで送られてきた値をPOSTで引き取り、その値をscore[]に代入し、それをscore.txtに書き込む…。 ということをしたいのですが、以下のソースでは、書き込む際にscore.txtの値にすべて0が入ってしまいます。 $score[$k] = $_POST["sel_$k"]; で値が送られているのは確認済みですが、if文でscore配列がすべて0にされてしまうようです。 その理由と対策がわかりません。 わかる方がいらっしゃいましたら是非教えてください。 <?php $fname = "score.txt"; $file = fopen($fname,"r"); for($l=0; $l<20; $l++){ $sc[$l]= fgets($file); $score[$l] = $sc[$l]; ) } fclose($file); print_r($score); $pointer=fopen("score.txt", "w"); flock($pointer, LOCK_EX); for($k=0; $k<20; $k++){ $score[$k] = $_POST["sel_$k"]; if($score[$k] == null){ $score[$k] =0; } fputs($pointer, "$score[$k]\n"); } flock($pointer, LOCK_UN); fclose($pointer);

    • ベストアンサー
    • PHP
  • ロック専用ファイルについて

    ロック専用ファイルについて すいません、またまた教えてください。m(_ _)m 一つのページに掲示板とカウンターの2つの別々のコードを含めようとしてます。 (現在、掲示板は問題なく動作していて、掲示板のコードの後に カウンターのコードを書こうとしています。) 掲示板にロック専用ファイルを作って、下記のようにしています。 $lock_fp = fopen("lock.txt", "w"); flock($lock_fp, LOCK_EX); ~掲示板ログの更新処理~ fclose($lock_fp); この後に、カウンターのコードを書いて、同じようにロック専用ファイルを使った 排他ロックの仕組みにしたいと思いましたが、そこでふと疑問が・・・。 flock()の排他ロック開始の行 ~ ロック解除の行(ロックファイルのファイルポインタ破棄の行) の間に書かれている全ての処理は、他の人がアクセスしているときは 自分の番になるまで行われないと思うのですが、 ロック解除の行の後に書かれている他のPHPの処理は普通に進んでいくのでしょうか? だとすれば、カウンター用のロック専用ファイルは 掲示板用のそれ(lock.txt)とは別のもの用意しないといけないと思うのですが、 その考え方で合っていますか? ものすごく基本的な質問な気がするのですが、参考書や参考サイトを見ても なかなか回答を上手に見つけられず困っています。 お手数ですが、ご教授ください。よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • ファイル作成

    $fp = fopen($filename1,"a+"); flock($fp,LOCK_EX); fputs($fp,$kisai); flock($fp,LOCK_UN); fclose($fp); としてファイルがなかったら作成するようにして$kisaiの内容を保存するようにしました。 それで問題なく実行できます。 しかし文字コードがANSIで保存されてしまいます。 UTF-8で保存させるようにするにはどうしたらよいでしょうか

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

    フォームに入力されたデータを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
  • PHPで外部ファイルを読み込むときの行の最後の改行の消し方について

    PHPについての質問です。 初歩的な質問ですがどうかお付き合いいただけたらと思います。 PHPで外部ファイルを読み込む際、csvファイルなどを1行ずつ読み込んだ場合、行の最後の改行まで代入されます。 例えば ////test.php/////////////// <?php $filename = list.csv; $fp = @fopen($filename,"r"); $data = @file($filename); @fclose($fp); ?> //////////////////////////// ////list.csv//////////////// 1,2,3,4,5 6,7,8,9,10 //////////////////////////// とする場合 $data[0]には 1,2,3,4,5 プラス改行のデータ $data[1]には 6,7,8,9,10 プラス改行のデータ が代入されます。 この改行のデータを除くためにはどのようにすればよいですか? 初歩的な質問で申し訳ないのですが、よろしくお願いします。

    • 締切済み
    • PHP
  • PHPでファイルポインタの移動

    現在。[EOF]になるまで1行読込んでは、ファイルポインタを移動させ すべての行を出力しています。 これをテキストの[EOF]よりも1行上のbbbbbbbbがある行(見た目上の最終行)のみを 出力したいのですがどうすればいですか? while(!feof($filepointer)){ $line = fgets($filepointer); print($line."<br />"); } ~log.txt~ aaaaaaaaaaaaa[改行コード] bbbbbbbbbbbbb[改行コード]←ココのみ取り出したい [EOF]

    • ベストアンサー
    • PHP
  • ファイルの書き込みについて

    ファイルの書き込みに関する質問です。 下のコードでは、 3行目「$ptr=fopen("kekka.txt", "w"); //ファイルを開く」 に問題があるというエラーが出ます。 しかし、文法的には問題はないと思うのですが・・・。 サーバーには、"kekka.txt"というファイルが置いてあります。 何かアドバイスがありましたら、よろしくお願いいたします。 <?php $x = "こんにちは";  $ptr=fopen("kekka.txt", "w");   //ファイルを開く    flock($ptr, LOCK_EX);      //ファイルをロックする      fputs($ptr, $x);      //書込む    flock($ptr, LOCK_UN);       //ロックを解除する  fclose($ptr);            //ファイルを閉じる ?>

    • ベストアンサー
    • PHP
  • ファイルを行ごとに比較するシェルスクリプトについて

    ファイルを行ごとに比較するシェルスクリプトをご教授ください。 例えば(master.txt)(a.txt)(b.txt)(c.txt)(ok.txt)(ng.txt)と4つのファイルがあり、 (master.txt)と(a.txt)の行を比較し(a.txt)の中のある行が(master.txt)の行と一致した場合(ok.txt)に (master.txt)の行と一致しなかった場合(ng.txt)に入れる。 その後(master.txt)と(b.txt)の比較し(a.txt)が使用したものと同じ(ok.txt)or(ng.txt)に入れる・・・ といったように繰り返していくシェルスクリプトはどのようにして作成するのでしょうか? txtファイルの中の行はランダムに入っており、x.txtの一行一行ををmaster.txtの全行と比較する必要があります。 自分で作ってみたものは、while文を2重で使い一行ずつ取り出しcase文で行が一致した物を(ok.txt)に入れる 所までは成功しているのですが、複数回繰り返す時にどのようなロジックで不一致行を(ng.txt)に入れる ことができるのかが考え付きませんでした。 よろしくお願いいたします。

専門家に質問してみよう