我认为这是 Linux 和 Windows 上字符默认编码的常见问题。然而,在我搜索互联网后,我没有任何简单的方法来自动修复它,因此我准备编写一个脚本来完成它。
场景如下:
我在 Windows 系统上创建了一些文件,其中一些具有非英文名称(在我的例子中特别是中文)。我使用 7-zip 将它们压缩成一个 zip 文件。之后我将 zip 文件下载到 Linux 并在 Linux 系统(Ubuntu 16.04 LTS)(默认存档程序)上解压文件。正如我所猜测的那样,所有非英文文件名现在都显示为一些损坏的字符!起初我认为使用 convmv 应该很容易,但是......
我试过 convmv,它说:“正在跳过,已经是 utf8”。什么都没有改变。
然后我决定使用 Python 编写一个工具来完成肮脏的工作,经过一些测试后我发现我无法将原始文件名与损坏的文件名相关联,(除非通过散列内容。)
这是一个例子。我设置了一个网络服务器来列出 Windows 上的文件名,一个文件在 python 中用“gbk”编码后显示为
u'j\u63a5\u53e3\u6587\u6863'
而且我可以在我的 Linux 系统上查询文件名。我可以直接用上面显示的名字创建一个文件,名字是正确的。我还可以将 unicode gbk 字符串编码为 utf8 编码并创建一个文件,名称也是正确的。 (因此我不能同时做它们,因为它们确实是同一个名字)。现在,当我读取之前提取的文件名时,应该是同一个文件。但是文件名完全不同:
'j\xe2\x95\x9c\xe2\x95\x99.....'
用 utf8 解码,它类似于 u'j\u255c\u2559...'。用gbk解码导致UnicodeDecodeError异常,我也试过用utf8解码再用gbk编码,结果还是别的。
总而言之,我无法在提取到 linux 系统后通过解码或编码来检查原始文件名。如果我真的想让一个程序来完成这项工作,我可能必须使用可能的一些编码选项重新归档,或者只使用我的脚本但使用文件内容哈希(如 md5 或 sha1)来确定其原始文件Windows 上的名称。
除了比较两个系统之间的文件内容之外,在上述情况下,我还有机会从 python 脚本中推断出原始名称吗?
最佳答案
通过对常见编码的一些实验,我能够反转你的 mojibake :
bad = 'j\xe2\x95\x9c\xe2\x95\x99\xe2\x94\x90\xe2\x94\x8c\xe2\x95\xac\xe2\x94\x80\xe2\x95\xa1\xe2\x95\xa1'
>>> good = bad.decode('utf8').encode('cp437').decode('gbk')
>>> good
u'j\u63a5\u53e3\u6587\u6863' # u'j接口文档'
gbk
- 通用中文 Windows 编码
cp437
- 常见的美国 Windows OEM 控制台编码
utf8
- 常见的 Linux 编码
关于python - Windows 文件名在 Linux 中显示损坏的字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42313150/