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-16-LE,而不是 UTF-8。

一串 ASCII 字符,如"abc",当编码为 UTF-16-LE 然后解码为 UTF-8 时,将看起来像"a\0b\0c\0",从而导致这种错误。

但解决方案不是\0去掉 nul 字节。只要您的数据都是 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应该给你一个名字列表,并且应该很明显哪个(s)意味着 UTF-16-LE 和哪个 UTF-8,所以你可以选择合适的一个。

当然不是每个系统都自带iconv;您可能需要改用其他工具。如果最坏的情况发生了,你总是可以用几行 Python 写一个。

于 2013-11-08T21:42:45.597 回答
0

如果您不想弄清楚这些 nul 字节来自哪里,而宁愿摆脱它​​们并交叉手指:

我不相信 GNU sed 或 BSD sed 中有任何东西可以让您指定除\n换行符之外的任何特殊字符。有很多方法可以将字面值 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 回答