■改行コード問題

Perl でこんな感じ。

$ chmod 755 otaken.pl
コード:

#!/usr/bin/perl

while($line = <STDIN>){
$line =~ s/[\x0d\x0a]+//;
# $line =~ s/\x0a//;
print "$line";
}

デフォルト、ウィンドウズ環境の改行を想定。
コメント部分は unix 系改行の場合。

実行: $ ./otaken.pl < 読込みテキストファイル > 出力先

----------------------------------------------------------------------

テキストファイル中の改行コード
Mac改行コード(0Dh)、
UNIX改行コード(0Ah)、
Windows改行コード(0D0Ah)

----------------------------------------------------------------------

OSによって、ファイル内に書かれたテキスト1行1行の最後を示す改行コード
(リターンを押した時に記録されるコード)が異なります。

OS名 改行コード名

WINDOWS CR(\r)+LF(\n)
MAC CR(\r)
UNIX LF(\n)

従って、それぞれのOSで編集されたテキストファイルを他のOSで認識させるには、
そのOSに合った改行コードに変換しなければなりません。
CGIスクリプトを設置するために大変重要な要件なので、よく理解してください

----------------------------------------------------------------------

UNIX => Windows


% perl -pe 's/\n/\r\n/' unixfile > winfile

UNIX => Macintosh


% perl -pe 's/\n/\r/' unixfile > macfile

Win => UNIX


% perl -pe 's/\r\n/\n/' winfile > unixfile

Windows => Macintosh


% perl -pe 's/\r\n/\r/' winfile > macfile

Macintosh => UNIX


% perl -pe 's/\r/\n/g' macfile > unixfile

Macintosh => Windows


% perl -pe 's/\r/\r\n/g' macfile > winfile

MacのファイルからWindows/Uninのファイルへの変換については,東京大学の川上洋生氏
よりオプション/g をつけるべきことを指摘していただきました.

----------------------------------------------------------------------

「テキスト・ファイル」や「テキスト形式」といえば、一般的には特殊なバイナリ・データを含まず、英数字や記号、漢字/ひらがな/カタカナなどの可読文字ばかりを含むデータ・フォーマットのことを指す。テキスト形式はデータとしての互換性も高く、多くのアプリケーションでそのまま取り扱うことができる。

 だが行末コードの違いにより、同じテキスト形式といっても、一般的には次の3種類が存在する(文字コードの違いは除く)。行末コードとは、改行コードなどと呼ばれることもある文字コード・シーケンスのことであり、PC/AT互換機では一般に[Enter]キーを押すと入力されるコードに相当する。
タイプ 行末コード
MS-DOS/Windows形式 「CR」と「LF」という2bytesの連続した文字コード。「CR」と「LF」は単独では存在せず、常にこの順に2bytes連続して使われる
UNIX/Linux形式 「LF」という1byteの文字コードのみ
Macintosh形式 「CR」という1byteの文字コードのみ
テキスト形式における行末コードの種類
OSによって、テキスト形式における行末コードが異なっている。「CR」は0x0D(16進数表現)、「LF」は0x0Aという制御文字コード。

 表中における「CR(Carriage Return、復帰)」とは、文字コードでいうと0x0D(10進数でいうと13)という制御文字であり、「LF(Line Feed、改行)」とは0x0A(10進数でいうと10)という制御文字を表している。CRはカーソルを左端へ移動させる操作、LFはカーソルを1行下へ移動させる操作を表す。一般にユーザーが入力する場合は[Return]キーや[Enter]キーを1回押すだけだが、表示の場合はCRとLFの両方が揃って初めて次の行の先頭へカーソルが移動する。そのため、OSなどによって、このような違いが出てくる。

 例えば次のような4行のサンプル・テキストを考えてみる。
1: Sample text
2: サンプルテキスト
3: 12345
4:

 4行目は空行である。これを各形式で表現してみると、次のようになる(文字コードはシフトJISとする)。jhdは16進数形式でダンプするコマンドである(標準コマンドではない)。黄色の部分が改行コードを表している。
C:\Text>jhd dos.txt …DOS/Windows形式
00000000 53 61 6D 70 6C 65 20 74 65 78 74 0D 0A 83 54 83 Sample text..サン
00000010 93 83 76 83 8B 83 65 83 4C 83 58 83 67 0D 0A 31 プルテキスト..1
00000020 32 33 34 35 0D 0A 0D 0A 2345....

C:\Text>jhd unix.txt …UNIX形式
00000000 53 61 6D 70 6C 65 20 74 65 78 74 0A 83 54 83 93 Sample text.サン
00000010 83 76 83 8B 83 65 83 4C 83 58 83 67 0A 31 32 33 プルテキスト.123
00000020 34 35 0A 0A 45..

C:\Text>jhd mac.txt …Mac形式
00000000 53 61 6D 70 6C 65 20 74 65 78 74 0D 83 54 83 93 Sample text.サン
00000010 83 76 83 8B 83 65 83 4C 83 58 83 67 0D 31 32 33 プルテキスト.123
00000020 34 35 0D 0D 45..

 UNIX形式またはMac形式のテキスト・ファイルをWindowsのメモ帳で開くと、改行コードが無視され、次のように1行につながって表示されてしまう(実際には内部では元の改行コードが保存されている。表示や操作が少しおかしくなるだけである)。
UNIXやMac形式のテキスト・ファイルをメモ帳で開いたところ
本来ならば4行で表示されるはずが、このように1行につながって表示されてしまう。特にMac形式のテキストの場合は、全選択してコピーし、例えばWord 2000に貼り付けると正しく4行になったように見えるが、行末移動キー([End]キー)を押すと、本来の行末記号(折れ曲がった矢印記号)を越えた位置までカーソルが移動したり、表に変換すると1行になってしまったりするなど、少々変わった挙動を示すことがある。

 このように、アプリケーションによってはMS-DOS/Windows形式(以下DOS形式)ではない改行コードをうまく扱えない場合がある。このような不具合を避けるため、Windows OS上で作業をする場合は、可能ならばDOS形式に変換しておくとよい。

操作方法

 改行コードをDOS形式にするには、本来ならばUNIXやMacからのデータ転送時にすませておくのが望ましい。例えばデータのエクスポート時に MS-DOS形式で書き出しておくとか、FTPならばバイナリ・モードではなく、テキスト・モードを使って転送するなどの方法がある。

 だがすでに転送してしまったファイルの場合は、Windows OSの標準環境だけならば、次のような方法で改行コードを変換することができる。
方法1―moreコマンドを使う方法

 コマンド・プロンプト上でmoreコマンドに通すことにより、UNIX形式の改行コードをDOS形式に変換することができる。
C:\Text>more < unix.txt > unix-converted.txt …moreコマンドに通す

C:\Text>jhd unix-converted.txt
00000000 53 61 6D 70 6C 65 20 74 65 78 74 0D 0A 83 54 83 Sample text..サン
00000010 93 83 76 83 8B 83 65 83 4C 83 58 83 67 0D 0A 31 プルテキスト..1
00000020 32 33 34 35 0D 0A 0D 0A 2345....

 ただしこの方法では、シフトJIS以外の漢字コードの場合は正しく変換できないし、Mac形式のファイルを変換することもできない(Mac形式の場合は、最後に0x0Aが付加されるだけ)。また[TAB]コード(文字コードでいうと0x09)は、(デフォルトでは)8桁ごとの空白文字に変換されてしまう。moreコマンドのオプションなどについては、「more /?」を実行すると表示される。
方法2―Internet Explorerを使う方法

 Windows TIPS「文字コードを変換する」で紹介した、Internet Explorerを使う方法でも改行コードをDOS形式に変換することができる。

 方法は文字コードの変換の場合と同じで、まず元のテキスト・ファイルをInternet Explorerで開き([ファイル]−[開く]メニューを使うか、ファイルをドラッグ&ドロップする)、そのまま保存するか、テキストを全選択してからほかのアプリケーショに貼り付ければよい。もし漢字コードの選択が違っていて、文字が正しく表示されていなければ、事前にエンコーディング形式を変更しておく必要がある。そうでないと、間違った文字コードでファイルが書き込まれてしまう。詳細については先のTIPSを参照していただきたい。

----------------------------------------------------------------------

◆ WinCVSでの改行コード

・ 長年(?)謎だったのがやっと理解できたので、個人的メモとして書き残しておこう。
激しく今更感はあるけど、サーチかけると似たような質問がたくさんあるので、結構ハマってる人多いみたい ^^;。

・ どうも調べたところによると、CVSでの大前提は「リポジトリ(CVSサーバ)側の改行コードはLF(0x0A)で統一しておくべし」ということらしい。

・ で、各プラットフォームの固有の改行コードがこれと異なる場合(Winで云えばCRLF(0x0D 0x0A))は「クライアント側が責任を持って変換する」。
つまり、WinベースのCVSクライアントなら、リポジトリから取ってくる段階でLF→CRLFに変換、書き戻す段階でCRLF→LF変換すること、ということらしい。

・ WinCVS使ってても、デフォルト設定ではこの変換をやってくれるので、ふつーはデフォルトで困ることは無いはず。

・ で、改行コードを混乱させるのが、WinCVSにある「checkout text files with Unix LF (0x0a)(日本語パッチ当ててる場合は「テキストファイルの改行コードをLF(0x0A)にする」)」という設定項目。

・ これ、何するかというと、要は上記の自動変換をしない、ってことなんですね。
「checkout」となってるけど、実際には取得時も格納時もどっちも改行コード変換をしません。

・ これをチェックしてると、CRLFベースのふつーのWinテキストを格納する際にCRLFで入れてしまうので、通常は使用しません(チェックボックスにチェックを入れちゃだめ)。
「通常は」ね。

・ じゃ、どういうときに使うかというと、上記の「大前提」が満たされてないとき。
例えば、リポジトリの内容が、はなから全てCRLF改行だった場合。

・ こういう場合、デフォルトの変換モードで取得するとLF→CRLF変換されちゃうので、結果として取得してきたテキストの改行コードは「CR CR LF(0x0D 0x0D 0x0A)」になっちゃうんですね(この辺がおバカと云えばおバカなわけだけど)。
格納時は再度CRLF→LF変換されるので、そのまま格納する分にはリポジトリ内のコードはCRLFのまま変わらないんですけど、編集して普通のCRLFが入った場合は、リポジトリ内ではその部分だけがLF改行になってしまうし、何より改行コードが変なので編集しにくい ^^;。

・ この現象が出る場合は、上記の「LFコードで取得」をチェックしておけば、取得時も格納時もCRLF→CRLFのままなので、リポジトリもローカルも整合は保てる、と。

・ ただ、これはあくまでも大前提が満たされてないときの緊急避難的な手段であって、ふつーは使うべきではないみたい。
プラットフォームが複数にまたがるようなプロジェクトの場合、整合が保てなくなるから。
特にMac*CVSユーザいると泣く羽目になりそう ^^;。

・ あ、ちなみに、cygwinベースのCVSだとかしこいので、CRCRLF問題は出ないみたいです。
でも、格納時にはLFへ変換しちゃうので、結果的にはリポジトリ内の改行コードは入り混じっちゃいますが※。
なので、結論としては、「大前提は守りませう」。

----------------------------------------------------------------------

----------------------------------------------------------------------

----------------------------------------------------------------------

----------------------------------------------------------------------

----------------------------------------------------------------------