linux/macOS下解压中文乱码的zip包

从 windows 下压缩的zip包如果文件或者目录名有中文,在典型的 linux 环境(如ubuntu)和 macOS 下按照正常zip解压都会乱码。google一下搜到的答案有两种,一种是hack一下unzip的代码重新编译,还有一种是另外写一个解压的工具代替unzip。

其实这是一个困扰了linuxer很多年的老问题了,能搜到好多人问和答,但至少在半年前(6月份)我遇到的时候,没有让我满意的简单的解决通用的方案。

当时我是,遇到产品的同事给了一个做好的交互原型,输出一个zip包,而基本上公司里其它技术都是用linux或者macOS。参考了搜到的解决方案,用 php 的 zip 扩展来解压,并转换 GBK 为 UTF-8 即可。

存到自己home目录下的bin里面, 比如放到 ~/bin/punzip,然后 chmod +x ~/bin/punzip,以后就可以比较自由的直接调用 punzip foo.zip 来解压了。

依赖了 php 的 zip 扩展,如果执行时提示“php zip extension is needed.”(比如默认macOS就没有加载zip扩展,ubuntu有),需要修改 php.ini 添加 extension=zip.so,具体按照提示中的手册页面做就好。


<?php
/**
 * 解压含有文件名为gbk编码的zip包,到当前目录
 */
if (!extension_loaded('zip')) {
    
printf("php zip extension is needed. See http://www.php.net/manual/en/zip.installation.php\n"$argv[0]);
    die;
}
if (!isset(
$argv[1])) {
    
printf("Usage: php %s filename\n\n"$argv[0]);
    die;
}
$f zip_open($argv[1]);
while (
$e zip_read($f)) {
    
$filesize zip_entry_filesize($e);
    
$filename iconv('GBK''UTF-8'zip_entry_name($e));
    if (!
$filesize) {
        
mkdir($filename); 
        continue;
    } else if (!
zip_entry_open($f$e)) {
        continue;
    }   
    
file_put_contents($filenamezip_entry_read($e$filesize));
    echo 
"$filesize\t$filename\n"
    
zip_entry_close($e);
}   
zip_close($f);


3 Responses to “linux/macOS下解压中文乱码的zip包”

  1. iveney says:

    另外必须在文件第一行加上

    #!/usr/bin/env php

    才能直接执行。

  2. teledi says:

    前两天遇到这个问题,文件名中所有中文被我直接清掉了~~

  3. Anson says:

    there is a easy way on linux. type “unzip -O gbk filename.zip”(if filename is messy coding,just use tab to complement it)

Leave a Reply