zip中压缩文件名称的中文编码

很抱歉提出类似于我之前的问题。 与上一个问题的区别在于,现在它在zip存档中,在提取之后和列出zip存档的内容之后,无法识别压缩文件名称中的中文编码:

$ unzip -l "严蔚敏数据结构(c语言版)教材及答案.zip" Archive: 严蔚敏数据结构(c语言版)教材及答案.zip Length Date Time Name --------- ---------- ----- ---- 25600 2000-01-04 23:27 ?+?+i- ??-?.doc 80896 2000-01-04 23:27 ?+??i- -+.doc 41984 2000-01-04 23:27 ?++?i- i+????-?.doc 52224 2000-01-04 23:27 ?+?+i- ??i?.doc 50688 2000-01-04 23:27 ?+??i- ??????.doc 54272 2000-01-04 23:27 ?++?i- -????-??????.doc 26112 2000-01-04 23:27 ?+?-i- ?????????_+?.doc 76288 2000-01-04 23:27 ?+-?i- -??-????-?.doc 53760 2000-01-04 23:27 ?+-?i- -+?+++?=.doc 53760 2000-01-04 23:27 ?+--i- ??.doc 7929077 2009-02-26 22:49 -???????+C????+??+?+?+pdf.pdf --------- ------- 8444661 11 files 

我想知道如何处理这个问题?

感谢致敬!


更新:

我已将此zip存档上传到,可以从http://www.mediafire.com/?dw87ee72m56evy9下载


我尝试使用chardet来确定压缩文件名称的编码:

 $ unzip -l "严蔚敏数据结构(c语言版)教材及答案.zip" | chardet : utf-8 (confidence: 0.99) 

但文件名确实是用utf-8编码的吗? 他们不应该使用外国编码吗? 我猜unzip -l的输出太多了,我怎么只把输出中的文件名单独输出作为chardet的输入?

尝试:

 unzip -O cp936 "严蔚敏数据结构(c语言版)教材及答案.zip" 

我会提取文件,然后做一个

 ls | chardet 

看看它说的是什么。

此外,您可以尝试不同的编码

 ls | iconv -f GB2312 

例如。 您可以使用iconv -l查看iconv已知的编码。

一旦确定了编码,我们假设是GB2312,你应该修改文件名,将编码改为UTF8

 for f in *; do g="$(iconv -f GB2312 <<<"$f")" mv "$f" "$g" done 

编辑

尝试对你的zip文件进行暴力攻击,转换为每个已知的编码,但在我看来,似乎没有一个是合理的

 #!/bin/bash iconv -l | sed 's|//$||' | while read enc; do printf "\n --- $enc ---\n\n" ls | iconv -cf "$enc" 2>/dev/null done 

通常文件名被解释为西方字符集。 因此,您必须首先将文件名从UTF-8转换回ISO,然后将“字节流”解释为GB2312返回UTF-8。 即:

ls | iconv -f UTF-8 -t ISO8859-1 | iconv -f GB2312 -t UTF-8

这不适用于您的特定文件,因此您可能想了解文件的创建方式(系统,程序,语言等)

另见http://en.wikipedia.org/wiki/Mojibake

你需要iconv ,但是convmvcconv是可选的。

 Step 1, find the correct char-encode converting chain. Step 2, rename files by a shell script. 

有时,转换链中存在错误的字符编码。 在enzotib的post中,你必须找到差距。

例如,utf8文件系统中名为“冼极.otf”的文件。

 touch 冼极.otf 

我必须做以下事情才能得到正确的名字“宋体.otf”。

 convmv --notest -f utf8 -t cp950 *.otf convmv --notest -f cp936 -t utf8 *.otf 

在有一个正确的名称之后,人们可能喜欢使用cconv进行简化的繁体中文转换,如下面的shell脚本。 在我的情况下,“宋体.otf”终于来了。

 #!/bin/sh # bash shell script mkdir TW for filename in *; do [ -d "$filename" ] || echo "$filename" ; done | while read filename; do filename_TW=`echo "$filename" | cconv -f UTF8-CN -t UTF8-TW` printf "\n --- $filename $filename_TW ---\n\n" #uncomment lines below if you've confirmed the names #mv "$filename" "TW/$filename_TW" #touch "$filename" done 

这是另一个与丹尼尔的post有关的例子。 在utf8文件系统中名为“ý¹úÖ¾.txt”的文件。

 touch ý¹úÖ¾.txt 

经过一些试验,我发现其正确的简体中文名称是“三国志.txt”

 ls | iconv -f utf-8 -t iso-8859-1 | iconv -f cp936 -t utf-8 

然后我将它重命名为繁体中文名称“三国志.txt”

 #!/bin/sh mkdir BACKUP for filename in *; do [ -d "$filename" ] || echo "$filename" ; done | while read filename; do filename_TW=`echo "$filename" | iconv -f utf-8 -t iso-8859-1 | iconv -f cp936 -t utf-8 | cconv -f UTF8-CN -t UTF8-TW` mv "$filename" "$filename_TW" touch "BACKUP/$filename" done