コマンドラインで文字コードや改行コードを調べる方法まとめ
コマンドラインで文字コードや改行コードを判定したく、やり方を調べた。Windows と Mac でそれぞれやり方に微妙な差異があったので、それぞれ検証してみた。
目次
今回の目標
今回は、コマンドラインで文字コードや改行コードを判定したいと考えているが、その際検証したい内容は以下のとおり。
- カレントディレクトリ配下のすべてのファイルを対象に検索したい
- 文字コード :
- BOM なし UTF-8 になっていないモノを知りたいので、Shift-JIS や EUC-JP なファイルを検出したい
- BOM 付き UTF-8 は BOM なし UTF-8 と別に検出したい
- 改行コード :
- LF に統一したいので、CR が含まれるファイル、CRLF で改行しているファイルを検出したい
検証に使用するファイル
検証に用意したファイルの内容は以下のとおり。いずれも VSCode の機能を利用して、文字コードと改行コードを設定した。
文字コード | 改行コード | 内容 | 注釈 |
---|---|---|---|
UTF-8 (BOM なし) | LF | 英文のみ | ASCII 扱いされる場合あり |
UTF-8 (BOM なし) | LF | 含日本語 | - |
UTF-8 (BOM なし) | CR+LF | 英文のみ | ASCII 扱いされる場合あり |
UTF-8 (BOM なし) | CR+LF | 含日本語 | - |
UTF-8 (BOM アリ) | LF | 英文のみ | - |
UTF-8 (BOM アリ) | LF | 含日本語 | - |
UTF-8 (BOM アリ) | CR+LF | 英文のみ | - |
UTF-8 (BOM アリ) | CR+LF | 含日本語 | - |
Shift-JIS | LF | 英文のみ | ASCII 扱い |
Shift-JIS | LF | 含日本語 | - |
Shift-JIS | CR+LF | 英文のみ | ASCII 扱い |
Shift-JIS | CR+LF | 含日本語 | - |
EUC-JP | LF | 英文のみ | ASCII 扱い |
EUC-JP | LF | 含日本語 | - |
EUC-JP | CR+LF | 英文のみ | ASCII 扱い |
EUC-JP | CR+LF | 含日本語 | - |
文字コードの基礎のおさらいとなるが、UTF-8・Shift-JIS・EUC-JP など大抵の文字コードは ASCII から拡張しているエンコード体系であり、これらのファイルには BOM が付いていないため、ASCII の範囲内の文字 (= アルファベット程度) しか出てこない場合は「文字エンコーディング」という概念が発生しないのだ。
世界中で使用されている様々な文字の符号化方式の多くは、ASCIIで使用されていない128番以降の部分に、その他の文字を割り当てたものである。
- 参考 : ASCII - Wikipedia
だから、エディタで Shift-JIS エンコードを指定して保存したとしても、アルファベットしか含んでいないファイルだった場合は、次開いたときには「UTF-8」なり「ASCII」なりに自動判定されることになる。ココはエディタが「(BOM なし) UTF-8」と表現するか、「ASCII」と表現するかの違いであり、エンコーディングの対象となる文字列が登場していない以上はそのテキストファイルの文字コードは未確定なのだ。
BOM 付き UTF-8 の場合は別で、ASCII の範囲の文字しか登場していなくても「BOM 付き UTF-8」と判定できる。バイト・オーダー・マークのおかげである。
Mac での調べ方
Mac での調べ方アレコレ。
file
コマンド
標準コマンドである file
コマンドを使うと、自然な表現でテキストファイルの内容を示してくれる。
$ file ./*
./EUC-JP - CRLF - EN.txt: ASCII text, with CRLF line terminators
./EUC-JP - CRLF - JP.txt: ISO-8859 text, with CRLF line terminators
./EUC-JP - LF - EN.txt: ASCII text
./EUC-JP - LF - JP.txt: ISO-8859 text
./Shift-JIS - CRLF - EN.txt: ASCII text, with CRLF line terminators
./Shift-JIS - CRLF - JP.txt: Non-ISO extended-ASCII text, with CRLF line terminators
./Shift-JIS - LF - EN.txt: ASCII text
./Shift-JIS - LF - JP.txt: Non-ISO extended-ASCII text
./UTF-8 - CRLF - EN.txt: ASCII text, with CRLF line terminators
./UTF-8 - CRLF - JP.txt: UTF-8 Unicode text, with CRLF line terminators
./UTF-8 - LF - EN.txt: ASCII text
./UTF-8 - LF - JP.txt: UTF-8 Unicode text
./UTF-8 BOM - CRLF - EN.txt: UTF-8 Unicode (with BOM) text, with CRLF line terminators
./UTF-8 BOM - CRLF - JP.txt: UTF-8 Unicode (with BOM) text, with CRLF line terminators
./UTF-8 BOM - LF - EN.txt: UTF-8 Unicode (with BOM) text
./UTF-8 BOM - LF - JP.txt: UTF-8 Unicode (with BOM) text
- 文字コード
- BOM 付き UTF-8 は判定できている。
file ./* | grep "(with BOM)"
で BOM 付きのファイルのみ特定などはできそう。 - Shift-JIS の判定ができてない。
- EUC-JP は ISO-8859 と判定された。
- BOM 付き UTF-8 は判定できている。
- 改行コード
- CRLF のファイルのみ表記され、LF の場合は未表記。
file ./* | grep "with CRLF"
で CRLF な改行コードのファイルは特定できそう。
- CRLF のファイルのみ表記され、LF の場合は未表記。
nkf
次に、前回紹介した nkf を使った場合。nkf は --guess
・-g
オプションで指定したファイルの文字コードや改行コードを判定できる。
Mac 版 nkf の場合、-g
だと文字コードのみの判定になってしまうので、改行コードもチェックするには --guess
を指定する必要があることに注意。
実行結果は以下のとおり。
$ nkf --guess ./*
./EUC-JP - CRLF - EN.txt: ASCII (CRLF)
./EUC-JP - CRLF - JP.txt: EUC-JP (CRLF)
./EUC-JP - LF - EN.txt: ASCII (LF)
./EUC-JP - LF - JP.txt: EUC-JP (LF)
./Shift-JIS - CRLF - EN.txt: ASCII (CRLF)
./Shift-JIS - CRLF - JP.txt: Shift_JIS (CRLF)
./Shift-JIS - LF - EN.txt: ASCII (LF)
./Shift-JIS - LF - JP.txt: Shift_JIS (LF)
./UTF-8 - CRLF - EN.txt: ASCII (CRLF)
./UTF-8 - CRLF - JP.txt: UTF-8 (CRLF)
./UTF-8 - LF - EN.txt: ASCII (LF)
./UTF-8 - LF - JP.txt: UTF-8 (LF)
./UTF-8 BOM - CRLF - EN.txt: UTF-8 (BOM) (CRLF)
./UTF-8 BOM - CRLF - JP.txt: UTF-8 (BOM) (CRLF)
./UTF-8 BOM - LF - EN.txt: UTF-8 (BOM) (LF)
./UTF-8 BOM - LF - JP.txt: UTF-8 (BOM) (LF)
# ちなみに -g オプションだとこうなる
$ nkf -g ./*
./EUC-JP - CRLF - EN.txt: ASCII
./EUC-JP - CRLF - JP.txt: EUC-JP
./EUC-JP - LF - EN.txt: ASCII
./EUC-JP - LF - JP.txt: EUC-JP
./Shift-JIS - CRLF - EN.txt: ASCII
./Shift-JIS - CRLF - JP.txt: Shift_JIS
./Shift-JIS - LF - EN.txt: ASCII
./Shift-JIS - LF - JP.txt: Shift_JIS
./UTF-8 - CRLF - EN.txt: ASCII
./UTF-8 - CRLF - JP.txt: UTF-8
./UTF-8 - LF - EN.txt: ASCII
./UTF-8 - LF - JP.txt: UTF-8
./UTF-8 BOM - CRLF - EN.txt: UTF-8
./UTF-8 BOM - CRLF - JP.txt: UTF-8
./UTF-8 BOM - LF - EN.txt: UTF-8
./UTF-8 BOM - LF - JP.txt: UTF-8
- 文字コード
- Shift-JIS・EUC-JP の判定は完璧。
- UTF-8 の BOM についても
--guess
オプションの方で分かる
- 改行コード
-g
ではなく--guess
オプションならきちんと調べられる
od
コマンド
改行コードを調べるのに od
コマンドが使える。
# -c オプション
$ od -c 'UTF-8 - CRLF - EN.txt'
0000000 U T F - 8 \r \n C R L F
0000013
# -a オプション
$ od -a 'UTF-8 - CRLF - EN.txt'
0000000 U T F - 8 cr nl C R L F
0000013
-c
と -a
とで違うのは制御文字の表示方法。パイプで繋げて grep
する時のやり方もちょっと変わる感じ。
# -c オプションに繋げる時
$ od -a 'UTF-8 - CRLF - EN.txt' | grep 'cr\s\snl'
# -a オプションに繋げる時
$ od -a 'UTF-8 - CRLF - EN.txt' | grep 'cr\s\snl'
同様に、cat -e
や cat -A
でも改行コードを表示できる。
目視確認になるので、少々使いづらいか。
Windows での調べ方
続いて Windows。といっても GitBash を入れていて、基本的な Linux コマンドは使える前提で。
file
コマンド
Windows GitBash にも file
コマンドが入っているので、Mac と同様に使える。
$ file ./*
./EUC-JP - CRLF - EN.txt: ASCII text, with CRLF line terminators
./EUC-JP - CRLF - JP.txt: ISO-8859 text, with CRLF line terminators
./EUC-JP - LF - EN.txt: ASCII text
./EUC-JP - LF - JP.txt: ISO-8859 text
./Shift-JIS - CRLF - EN.txt: ASCII text, with CRLF line terminators
./Shift-JIS - CRLF - JP.txt: Non-ISO extended-ASCII text, with CRLF line terminators
./Shift-JIS - LF - EN.txt: ASCII text
./Shift-JIS - LF - JP.txt: Non-ISO extended-ASCII text
./UTF-8 - CRLF - EN.txt: ASCII text, with CRLF line terminators
./UTF-8 - CRLF - JP.txt: UTF-8 Unicode text, with CRLF line terminators
./UTF-8 - LF - EN.txt: ASCII text
./UTF-8 - LF - JP.txt: UTF-8 Unicode text
./UTF-8 BOM - CRLF - EN.txt: UTF-8 Unicode (with BOM) text, with CRLF line terminators
./UTF-8 BOM - CRLF - JP.txt: UTF-8 Unicode (with BOM) text, with CRLF line terminators
./UTF-8 BOM - LF - EN.txt: UTF-8 Unicode (with BOM) text
./UTF-8 BOM - LF - JP.txt: UTF-8 Unicode (with BOM) text
nkf
前回の記事で紹介した Windows 版 nkf を使う方法。Windows 版は --guess
でも -g
でも同じで、どちらでも文字コード・改行コードを両方判定してくれる。
--guess
(-g
) オプションを使ってみた結果は以下のとおり。
# ある日の検証結果
$ nkf -g ./*
./EUC-JP - CRLF - EN.txt:ASCII (CR)
./EUC-JP - CRLF - JP.txt:EUC-JP (CR)
./EUC-JP - LF - EN.txt:ASCII (CR)
./EUC-JP - LF - JP.txt:EUC-JP (CR)
./Shift-JIS - CRLF - EN.txt:ASCII (CR)
./Shift-JIS - CRLF - JP.txt:Shift_JIS (CR)
./Shift-JIS - LF - EN.txt:ASCII (CR)
./Shift-JIS - LF - JP.txt:Shift_JIS (CR)
./UTF-8 - CRLF - EN.txt:ASCII (CR)
./UTF-8 - CRLF - JP.txt:UTF-8 (CR)
./UTF-8 - LF - EN.txt:ASCII (CR)
./UTF-8 - LF - JP.txt:UTF-8 (CR)
./UTF-8 BOM - CRLF - EN.txt:UTF-8 (CR)
./UTF-8 BOM - CRLF - JP.txt:UTF-8 (CR)
./UTF-8 BOM - LF - EN.txt:UTF-8 (CR)
./UTF-8 BOM - LF - JP.txt:UTF-8 (CR)
# 別の日の検証結果
$ nkf -g ./*
./EUC-JP - CRLF - EN.txt:ASCII (LF)
./EUC-JP - CRLF - JP.txt:EUC-JP (LF)
./EUC-JP - LF - EN.txt:ASCII (LF)
./EUC-JP - LF - JP.txt:EUC-JP (LF)
./Shift-JIS - CRLF - EN.txt:ASCII (LF)
./Shift-JIS - CRLF - JP.txt:Shift_JIS (LF)
./Shift-JIS - LF - EN.txt:ASCII (LF)
./Shift-JIS - LF - JP.txt:Shift_JIS (LF)
./UTF-8 - CRLF - EN.txt:ASCII (LF)
./UTF-8 - CRLF - JP.txt:UTF-8 (LF)
./UTF-8 - LF - EN.txt:ASCII (LF)
./UTF-8 - LF - JP.txt:UTF-8 (LF)
./UTF-8 BOM - CRLF - EN.txt:UTF-8 (LF)
./UTF-8 BOM - CRLF - JP.txt:UTF-8 (LF)
./UTF-8 BOM - LF - EN.txt:UTF-8 (LF)
./UTF-8 BOM - LF - JP.txt:UTF-8 (LF)
- 文字コード : Mac と同様
- Shift-JIS・EUC-JP の判定は出来ている。
- UTF-8 は BOM の有無が分からない。
- 改行コード
- ファイル単体で調べると比較的正しく判定できるのだが、複数ファイルを一括で判定しようとすると全て CR もしくは LF 扱いで出力されてしまった。
どうも改行コードの判定が Mac 版と比べるとイマイチ。また、UTF-8 の BOM も分からない。バージョンの違いだろうか。
od
コマンド
Windows GitBash でも od
コマンドが使える。Mac 版の od
コマンドと全く同じだったので結果は省略。
grep -lzUP
コマンド
これは改行コードだけを調べる方法。CR を含むファイル名を列挙する。
$ grep -lzUP '\r' ./*
./EUC-JP - CRLF - EN.txt
./EUC-JP - CRLF - JP.txt
./Shift-JIS - CRLF - EN.txt
./Shift-JIS - CRLF - JP.txt
./UTF-8 - CRLF - EN.txt
./UTF-8 - CRLF - JP.txt
./UTF-8 BOM - CRLF - EN.txt
./UTF-8 BOM - CRLF - JP.txt
オプションの内容は以下のとおり。
-l
: マッチしたファイル名のみを表示する-z
: 改行の代わりに NULL 文字で区切ったものとして扱う-U
:grep
のデフォルトの挙動が CR を取り除く挙動なので、このオプションでバイナリとして認識させ、CR を除去しないようにする-P
: Perl 互換の正規表現 (PCRE) として扱う。Grep のバージョン等によっては使えない。
どうも Mac では同じオプションを使えなかったので、Windows 側で紹介。多分 GNU Grep かどうかの違いなのかと。
文字コード・改行コードの調べ方まとめ
Mac の場合も、Windows GitBash の場合も、全体的には file
コマンドの結果を grep
して使うのが手軽で良さそうだ。nkf は導入 OS やバージョンによって細かな挙動が微妙だった。よくよく調べて使う必要がありそうだ。
# 以下で「CR」を含むファイルと BOM 付き UTF-8 のファイルを調べる
$ file ./* | grep -e 'with CR' -e 'with BOM'
# 以下で UTF-8 か ASCII でないファイルを調べる (「Non-ISO extended-ASCII text」はヒットさせる)
$ file ./* | grep -v 'UTF-8 Unicode' | grep -v ' ASCII'
用意していた検証用ファイルでの結果は以下のとおり。
$ file ./* | grep -e 'with CR' -e 'with BOM'
./EUC-JP - CRLF - EN.txt: ASCII text, with CRLF line terminators
./EUC-JP - CRLF - JP.txt: ISO-8859 text, with CRLF line terminators
./Shift-JIS - CRLF - EN.txt: ASCII text, with CRLF line terminators
./Shift-JIS - CRLF - JP.txt: Non-ISO extended-ASCII text, with CRLF line terminators
./UTF-8 - CRLF - EN.txt: ASCII text, with CRLF line terminators
./UTF-8 - CRLF - JP.txt: UTF-8 Unicode text, with CRLF line terminators
./UTF-8 BOM - CRLF - EN.txt: UTF-8 Unicode (with BOM) text, with CRLF line terminators
./UTF-8 BOM - CRLF - JP.txt: UTF-8 Unicode (with BOM) text, with CRLF line terminators
./UTF-8 BOM - LF - EN.txt: UTF-8 Unicode (with BOM) text
./UTF-8 BOM - LF - JP.txt: UTF-8 Unicode (with BOM) text
$ file ./* | grep -v 'UTF-8 Unicode' | grep -v ' ASCII'
./EUC-JP - CRLF - JP.txt: ISO-8859 text, with CRLF line terminators
./EUC-JP - LF - JP.txt: ISO-8859 text
./Shift-JIS - CRLF - JP.txt: Non-ISO extended-ASCII text, with CRLF line terminators
./Shift-JIS - LF - JP.txt: Non-ISO extended-ASCII text
- 参考 : grepでAND検索とOR検索 - Qiita
- 参考 : 指定した文字列を含まない行を抽出するためのコマンド | ハックノート
- 参考 : ファイルの文字コード&改行コードを確認・変換するためのツールまとめ | DevelopersIO
結果的に nkf
は調査コマンドに含めなかったけど、変換処理は任せられるので、nkf
は入れておいて損はないかと。