これは車輪の再発明。
WindowsとLinuxを行き来していると、テキストファイルの文字コードと改行コードを変換したくなる事が結構ある。文字コードの変換だけならiconv、改行コードの変換だけならdos2unixやtrやPerlなどを使えば済む。もっとも大抵は文字コードと改行コードの両方とも変換する訳で、その場合はnkfやqkcで一括変換すると楽だ。
ここまでは良くある話だ。
つい最近、Windowsで作成したスクリプトをUbuntu上で使おうとしてCP932&CRLFからUTF-8&LFに変換しようとしたらnkfもqkcも入ってなかった。iconvは入ってたので文字コードの変換はできるが、改行コードを変換するdos2unixの類も入ってなかった。
で、普通なら「nkfでも入れるか」となるのだが、へそ曲がりの私はiconvと手持ちのツールを組み合わせて即席の変換スクリプトを作ることにした。
#!/bin/sh # win2unix.sh iconv -f CP932 -t UTF-8 $* | tr -d "\r"
何もかも決めうちだけど、自分用なので問題ない。
逆の変換はこんな感じになる。
#!/bin/sh # unix2win.sh perl -pe 's/\n/\r\n/' $* | iconv -f UTF-8 -t CP932
当初はPerlではなくsedを使っていて、うまく変換されなくて悩んだ。sedでは行末の改行コードにマッチしないことに気づくまでに随分時間を浪費してしまった。
もし「処理対象ファイルの末尾に必ず改行が1個以上ある」と仮定しても構わないなら、sedを使ってこんな風にしても大丈夫だろう。
#!/bin/sh # unix2win.sh sed -e 's/$/\r/' $* | iconv -f UTF-8 -t CP932
もっともファイル末尾に改行がないファイルを処理すると残念な結果になるのだが……。
ちなみにRubyを使う人なのになぜPerlを使ったかというと、LinuxやFreeBSDを使う時に依存関係の都合でPerlが入っていることが多いからだ。
ところで仕事用のWindowsマシンにはGnuWin32のツールが入っているので、このシェルスクリプトをバッチファイル化してWindows上でも変換できるようにしてみた。
@echo off :: win2unix.bat iconv -f CP932 -t UTF-8 %* | tr -d "\r"
これで事前に変換しておくのが楽になった。今まではnkfを使っていたのだけど、使う度にオプションを忘れてしまっていて、毎度調べ直していた。
ちなみにUnixからWindows用への変換は少し変わっている。
@echo off :: unix2win.bat iconv -f UTF-8 -t CP932 %*
何故かiconvを通しただけで改行コードも変換されている。libiconv 1.8付属のiconv.exeだが、何でだろう?