シェルスクリプトやコマンドラインで,テキストファイルの文字コードを自動判別する方法です
nkf を使う
head -n 1000 ファイル名 | nkf -g
nkf -g ファイル名でも良いですが,nkfは遅いので,ファイルサイズが大きくなると処理に時間がかかります.アホみたいに待つ羽目になります.
実際に使うときは,ファイルの先頭1000行ぐらいをheadで切り取ってから nkf に渡すほうが良いでしょう
uchardet を使う
uchardet は比較的あたらしいツールです.高速に文字コードが判別できます.
$ sudo apt-get install uchardet
macportや homebrewでもパッケージが用意されています
使い方は
$ uchardet ファイル名
uchardet の出力は iconv 互換の文字列なので,そのままiconvコマンドに渡すことができます
例えばこのような形で
encoding=`uchardet 元ファイル` iconv -f $fromcode -t utf-8 > 出力先ファイル名
ベンチマーク
nkfと uchardet で処理時間はどの程度違うのでしょうか?
1.1GBのcsvファイル(2200万行)でベンチマークを取りました.測定条件は以下の通り
ベンチマーク結果
コマンド | 処理時間 |
nkf -g | 52.3秒 |
uchardet | 0.47秒 |
head -n 1000 | nkf -g | 0.013秒 |
head -n 1000 | uchardet | 0.014秒 |
比較のために head -n 1000 の結果 nkf で判定するパターンにくわえて, uchardet で判定するパターンも測定しています
結果を見ると
- データサイズが大きいときは head でファイルを切り出すのが効果的
- nkfもuchardetもほぼ同じ処理時間
- uchardet はやっぱり早い
- 1.1GBのファイルが 一秒以下で判別できてます
このベンチはRAMディスクを使ってるのでdisk I/Oの負荷を無視した測定結果になっています.実際には disk I/Oがボトルネックになることもあるので uchardetを使うときも headを組みわせるなどしたほうがいいかもしれません.