python - Windows 文件名在 Linux 中显示损坏的字符

标签 python linux unicode encoding utf-8

我认为这是 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/

相关文章:

ruby - 读取文件时如何避免被 UTF-8 BOM 绊倒

javascript - 如何正确显示字符串中的项目符号点?

python - 未在 Tornado 中设置 Content-Type header

Python程序第一次执行时间太长?

c - C 中的共享内存和缺少 MAP_ANONYMOUS?

linux - 如果存在另一行,则 Bash 替换行

php - 将命名的 HTML 实体转换为数字 HTML 实体

python - 从文本文件中提取 block

python - if 语句条件不适用于循环中的最后一个 i

将多个结构转换为 char 字符串