0

次の形式の csv ファイルを postgres にコピーしています。

 0   "the"
 1   "parative Philosophy 62 June 2007 pp 125130 More on Jonas and Process Philosophy in The Legacy of Hans Jonas Judaism and the Phenomenon of Life Edited by Havakp TiroschSamuelson"

この csv ファイルを postgres にコピーすると、次のエラーが発生します。

copy dict from '/home/r.csv' with delimiter E'\t';
ERROR:  invalid byte sequence for encoding "UTF8": 0x00

「sed s/\/\g' ./r.csv」を使用して特殊文字を削除しようとしました。ただし、特殊文字は削除されません。LinuxまたはPythonを使用して特殊文字を削除する方法はありますか

私のオペレーティングシステムはubuntu 12.04 ltsです。

4

2 に答える 2

3

問題は、ファイルが実際には UTF-8 ではなく UTF-16-LE であることです。

のような ASCII 文字の文字列は"abc"、UTF-16-LE としてエンコードされてから UTF-8 としてデコードされると、 のよう"a\0b\0c\0"になり、まさにこの種のエラーが発生します。

しかし、解決策は\0nul バイトを取り除くことではありません。これは、データがすべて ASCII (またはすべての ASCII と Latin-1 の特定のサブセット) である限り機能するように見えますが、それ以外の場合はすぐにゴミまたはエラーが発生します。たとえば、'倀'UTF-16-LE としてエンコードされ、UTF-8 としてデコードされた CJK 文字 U+5000 () は のよう'\0P'に見えますが、nul バイトを取り除いて'P'. '偐'(さらに言えば、 U+5050, , を として解釈したくありません'PP'。)

正しいことは、ファイルを再コード化することです。例えば:

iconv -f UTF-16-LE -t UTF-8 r.csv >r8.csv

のすべてのインストールがiconv同じ名前をサポートしているわけではなく、どの名前が正規のものかわかりません。iconv --list |grep -i utf名前のリストが表示され、どれが UTF-16-LE を意味し、どれが UTF-8 を意味するかが明確になるはずなので、適切なものを選択できます。

もちろん、すべてのシステムに が付属しているわけではありませんiconv。代わりに別のツールを使用する必要がある場合があります。最悪の場合は、Python の数行でいつでも記述できます。

于 2013-11-08T21:42:45.597 に答える
0

これらの nul バイトがどこから来たのかを把握したくない場合は、それらを取り除き、指を交差させます。

\nGNU sed または BSD sed には、改行以外の特殊文字を指定できるものはないと思います。リテラルの nul バイトを引数に取得する方法はたくさんあります… しかし、とにかくそれを文字列の末尾として扱うことにsed賭けます。sed

と戦うよりsed、Pythonでやりましょう。正規表現は必要ありません。ただのstr.replace. ファイルが十分に小さいため、メモリに読み込むのに問題がない場合:

with open('r.csv', 'rb') as fin, open('r2.csv', 'wb') as fout:
    fout.write(fin.read().replace('\0', ''))

…それには大きすぎるが、有効な ASCII に十分近い場合は、それを行と考えるのが理にかなっている:

with open('r.csv', 'rb') as fin, open('r2.csv', 'wb') as fout:
    for line in fin:
        fout.write(line.replace('\0', ''))
于 2013-11-08T22:13:10.637 に答える