かなり大きな (約 15 GB) テキスト ファイルのセットがあります。これらのファイルは基本的に資格情報を含む単純なデータベースであり、その中の資格情報は 128 文字の ASCII 範囲外 (アクセント付き文字など) であることがよくあります。
これらのファイルの一部を次のように並べ替えようとすると、
sort -u input.txt -o output.txt
...次のエラーが発生します:
sort: string comparison failed: Invalid or incomplete multibyte or wide character
sort: Set LC_ALL='C' to work around the problem.
を使用すると、やなどLC_ALL=C
の文字を扱うコマンドを高速化できるという記事をたくさん読んだことがあります。sort
grep
ステファン・シャゼラスの素晴らしい答えこのトピックについては、特に自分のデータセットでそれを使用することの影響について心配しています。
これらのファイルを実行するLC_ALL=C sort -u
と、非 ASCII 文字が削除される可能性はありますか?
もしそれが、代わりにすべてを修正/削除するにはどうすればいいでしょうか?無効または不完全なマルチバイト文字またはワイド文字「これらのファイルから」を削除し、LC_ALL=C
?を使用せずに並べ替えることができます。
答え1
これらのファイルに対して LC_ALL=C sort -u を実行すると、非 ASCII 文字が削除される可能性はありますか?
この場合はそうではありません。sort
バイト値を文字に変換しようとするのではなく、バイト値を直接処理します。
ただし、同じことが他のツールに必ずしも当てはまるわけではありません。C (言語) で書かれたプログラムは、このように動作する可能性が最も高くなります。Python 3 などの、バイトと文字の区別が明確な言語で書かれたプログラムは、文字セットに準拠しない入力を完全に拒否する必要があります。また、エラーを無視して?
代わりに � または を出力するような、下手に書かれたプログラムも想像できます。
もしそうなら、これらのファイルからすべての「無効または不完全なマルチバイトまたはワイド文字」を修正/削除して、LC_ALL=C を使用せずに並べ替えられるようにするには、代わりに何ができるでしょうか?
すべて同じファイル エンコーディング (UTF-8 が望ましい) が使用されていること、およびロケールで同じエンコーディングが使用されていることを確認してください。有効な UTF-8 ファイルであれば、ファイルの大きさに関係なく、エラーが発生することはありません。
答え2
sort
、、、などgrep
のさまざまな Bash ツールにファイルをパイプする必要が生じたため、承認された回答に示されている「適切な解決策」、つまり最初にすべてを UTF-8 に変換する方が安全だと判断しました。これは予想よりも少し難しくなりましたが、ファイルが ASCII かUTF-8 かを判断するのに が信頼できないことに気づくのにしばらく時間がかかりました (ファイル全体をチェックしないため)。そのため、後世のためにこの回答をここに掲載します。awk
wc
tr
file
ファイルのエンコーディングを確実に判断するには、まずuchardet
パッケージがCygwinインストーラー経由でインストールされていることを確認するか、apt-cygを実行し、以下を実行します。
uchardet *.txt
または、Cygwin を使用していない場合は、次のようになります。
chardet *.txt
chardet
リストされているすべてのファイルをASCII
独自のフォルダーに移動し、for
そのフォルダーで次のループを実行します。
for i in *.txt; do iconv -f ASCII -t UTF-8 "$i" >> "${i%.txt}_utf.txt"; done;
.txt
フォルダー内のすべてのファイルをループし、utf
サフィックスが追加された UTF-8 バージョンを作成します。
再度実行するとuchardet *.txt
、一部のファイルが と表示されることがありますASCII
。これは、ASCIIがUTF-8のサブセットであるためです。単にこれらのファイルには、128 ビットの ASCII 範囲外の文字が含まれていないことを確認します。
sort
これで、を使用せずに実行できるはずですLC_ALL=C
。