- ベストアンサー
perlでの改行コードの置換
perlで改行コードを置換したいのですが・・・ もとのファイルはS-JISコードでその中身をEUC(UNIXで使用するために)に変換します。ここまではOKなのですが、改行コードがうまく行きません。 改行コードをUNIXで使うためにLFだけにしようと思い、 $line =~ s/\r\n/\n/g; (これは\r\nで引っかからない) とか $line =~ s/\n/\x0A/g; とかにしてみたのですがうまく行きません。 どのようにすればよろしいでしょうか?
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
えーと、それはおそらく、binmode関数に対して出たエラーではありません。 \x81は漢字の始まりを示すキャラクターですので、ファイルディスクリプタ(今回の場合は文字列「OUTPUT」のこと)に漢字が使われている、という意味になります。 近くにそれっぽいエラーが出ているところありませんか? 秀丸の「行番号の計算方法」が「エディタ的」になってないかどうかも確認してみてください。
その他の回答 (4)
やっと分かりました(^_^; 全部Windows上でやってるんですね(^_^; えとですね。 いくら処理をしても、書き込み時に強制的に改行文字が変化してしまいますので、現状のままではどんな処置をしても駄目です。 これは Perl の仕様ですので、お望みの処理を行うためにはバイナリモードで書き込みを行わなければいけません。 具体的には、書き込み用にファイルをオープンする際、 open(OUT, '>data.txt'); とまあ、このような処理を入れていると思いますが、この直後に、 open(OUT, '>data.txt'); binmode(OUT); こういう処理を入れてください。これで、改行文字がCR+LFに変換されなくなります。 なお、UNIX上ではbinmode関数のこのような使い方は意味を成しませんのでご注意を。
補足
ありがとうございます。はじめに作業環境を伝えておけばおかったのですが・・・ 上のように open OUTPUT, ">$out_filename"; binmode (OUTPUT); とやったのですが、 Unrecognized character \x81 at ssjis2euc.pl line 26 と26行目、丁度binmode (OUTPUT);の行でエラーが出ている(?)ようです。私のマシンにはこの関数bimodeが入っていないということなのでしょうか?
えと、気づいたことがあるので補足を。 その処理が正しく行えているかどうかの確認はどうやってなさってるのでしょうか? 確認は必ずUNIX上で行わないと、ブラウザやFTPを通したりすると改行コードはCrLfに戻ってしまいます。 また、WindowsのみでHTTPサーバーを上げてテストなどを行っているときは、「¥n」で「CrLf」の2文字をあらわします(httpサーバーの仕様によると思いますが)。 そのへん確認してみてください。
補足
WINDOWS上でエディタを2つ使用して確認しています。 まず、あるテキストファイル(SJIS)を「秀丸エディタ」で開いてから名前をつけて保存をするときに「文字コードをEUCで改行コードをLF」と選択します。そしてこの保存したEUCコードのファイルを「MIFES」で開くと改行の部分がきちんとLF(16進の0A)だけとなっています。 しかし、これをperlで改行部分を処理して、元々の改行部分(CR+LF)のCRを削除したいのですが・・・「MIFES」で開いてみても、改行部分がCR+LF(0D,0A)となってしまって、削除できでいないということなのですが。
とすると、何らかの理由で最初から改行文字がUNIX形式になってるってことですね。 改行文字に¥rが含まれていないのだから、反応しなくて当然です。 そういう場合は何もしなくていいんですよ。
補足
いや、そのままUNIXで開くと、^M(おそらくCRだとおもうのですが・・・)と表示されてしまいます。
これはですね。 バグなのかどうか知りませんが、一部のエスケープシーケンスは通常のスカラー変数に入っているときと $_ に入っているときとでは扱いが変わる(らしい)というのが原因です。 ですから、MS-DOS系改行コードである \r\a をUNIXの改行形式に治すには、 $_ = $line; s/\r//g; $line = $_; とします。俺が作ったフリーソフトはこれで正常動作してます。
補足
やってみたのですが、 s/\n/\r/g; でやるときちんと改行(CR+LF)が\r(CR)に変換されるのですが、 目的の\r(CR)だけを取り除く s/\r//g; としても改行(CR+LF)の\r(CR)が引っかかりませんでした・・・ 他の方法なにかありますでしょうか。
お礼
原因がわかりました。binmode(OUTPUT);のあとにコメント#を入れていたのですが、その#の前に全角のスペースが入っていたためと思われます。その全角スペースを半角スペース変更したら動きました。 本当にありがとうございました!!