这里有一些关于 zip 文件中存储为流的文件名称中的非 ASCII 字母的问题 (希伯来语,中国人,日语或韩语)。然而,所提供的解决方案都没有帮助我处理来自 Windows 计算机的带有西里尔字母的 zip 文件。
该文件本身有一个西里尔字母名称(Космос.zip- 可下载链接)。这是一个零长度内容的存档,仅供说明之用。
unzip -l
印刷:
Archive: Космос.zip
Length Date Time Name
--------- ---------- ----- ----
0 2017-05-03 18:19 ɫ�����/ict_inf.pdf
--------- -------
0 1 file
丑陋ɫ�����
代表字节序列C9 AB DF E8 AB DF BC AB DF
。
我知道(通过使用 GMail 预览功能)这应该是
Archive: Космос.zip
Length Date Time Name
--------- ---------- ----- ----
0 2017-05-03 18:19 РосКосмос/ict_inf.pdf
--------- -------
0 1 file
那就是我们需要映射C9 AB DF E8 AB DF BC AB DF
到РосКосмос
.
有几种常用的 8 位西里尔字母编码:CP1251、CP866、ISO8859-5,但是它们会将这个字编码为不同的字节序列:
Р о с К о с м о с
CP866: 90 AE E1 8A AE E1 AC AE E1
CP1251: D0 EE F1 CA EE F1 EC EE F1
ISO8859-5: C0 DE E1 BA DE E1 DC DE E1
显然,常用的 8 位西里尔字母编码都不会像这样将输入名称解码为输出名称。这里有一些更复杂的事情在起作用。
如果我们知道如何解码名称,那么使用适当的find
脚本在提取后重命名文件就会很容易(https://unix.stackexchange.com/a/252000/17649),例如
find -mindepth 1 -exec sh -c 'mv "$1" "$(echo "$1" | here-goes-the-decoding pipeline )"' sh {} \;
或者转化率公用事业。
答案1
我在 OpenNET.ru 论坛上找到了一个解决方案,这是一个流行的俄语资源,自 1996 年以来一直致力于开源软件和技术。在 OpenNET 上发布Info-ZIP 曾经是一套在运行 MS-DOS 的计算机上处理 ZIP 档案的流行工具,它认为在 MS-DOS 上只有一种 8 位编码,即 CP850,因此所有文件名都会自动通过CP850->CP1252
转换运行。 CP1252 可能被选为最流行的 ISO-8859-1 字符集编码近似值。
因此,在提取包含西里尔文文件名的存档后运行的正确查找命令是
find -mindepth 1 -exec sh -c 'mv "$1" "$(echo "$1" | iconv -f cp1252 -t cp850 | iconv -f cp866 )"' sh {} \;
有趣的是,人们可以找到不使用 CP1252 而是使用 ISO-8859-1 的建议。情况似乎并非如此,因为我遇到的一些档案在转换成功iconv -f iso8859-1 -t cp850
时转换失败了iconv -f cp1252 -t cp850
。
回到单个角色
Р о с К о с м о с
CP866: 90 AE E1 8A AE E1 AC AE E1
现在应用 CP850 -> CP1252 结果为C9 AB DF E8 AB DF BC AB DF
.正是我们观察到的顺序。
另一个有用的命令是
unzip -l РосКосмос.zip | grep -aEv '^Archive:' | iconv -f iso8859-1 -t cp850 | iconv -f cp866
从存档中获取文件列表
Length Date Time Name
--------- ---------- ----- ----
0 2017-05-03 18:19 РосКосмос/ict_inf.pdf
--------- -------
0 1 file
过滤掉以 开头的行Archive:
是一种保护措施,可以隐藏存档名称以防止转换。
答案2
与“最近”infozip 一起使用的 ZIP 文件显示正确的文件名:
unzip -l Russian-Космос.zip
Archive: Russian-Космос.zip
Length Date Time Name
--------- ---------- ----- ----
0 2017-05-03 18:19 РосКосмос/ict_inf.pdf
--------- -------
0 1 file
РосКосмос/
并且 unzip在解压时 正确创建目录。
infozip 很久以前就添加了 UTF-8 支持。我的 Ubuntu 上的可执行文件:
UnZip 6.00, 20 April 2009
Zip 3.0, July 5th 2008
所以你的问题可能是一个古老的InfoZip版本(或者是没有UTF-8支持编译的版本)
在我的版本中,strings /usr/bin/unzip | grep -A8 -B8 'UTF-8'
除其他外,产生:
ZIP64_SUPPORT (archives using Zip64 for large files supported)
LARGE_FILE_SUPPORT (large files over 2 GiB supported)
other
UTF-8
UNICODE_SUPPORT [wide-chars, char coding: %s] (handle UTF-8 paths)
USE_DEFLATE64 (PKZIP 4.x Deflate64(tm) supported)
USE_UNSHRINK (PKZIP/Zip 1.x unshrinking method supported)
这似乎与编译/构建选项有关
答案3
zip 的这个问题已经固定的在最近的far2l 文件和存档管理器。为了让 far2l 的 zip 旧字符集检测正常工作,您的系统语言设置应该与创建存档的系统上设置的语言设置相匹配(Windows 的内部“zip 文件夹”工具使用相同的逻辑)。你也可以做
LANG=ru_RU.UTF-8 far2l
答案4
OEM 代码页选择在 vanilla unzip 和 vanilla p7zip 中均被破坏。我制造了一个修补解决这个问题并且有适用于 Ubuntu 的 ppa使用应用了此补丁的 p7zip。