unzip

作者:Greg Roelofs

尽管我们都热爱 Linux,但不可否认的是,我们偶尔必须强迫自己去处理 DOS/MS-Windows 世界,即使是间接地。对于我们中的一些人来说,这涉及到拥有一个双启动系统(可能是通过 LILO—LInux LOader—或 OS/2 的 Boot Manager),但即使是我们这些设法避免这种命运的人,迟早也会遇到源自某种 DOS 或 Windows 系统的文件。 很可能,其中一些文件将以 .zip 结尾——这就是 unzip 命令的用武之地。

unzip 是一个免费实用程序,用于处理 zip 文件,正如这些东西通常被称为的那样。Zip 文件实际上是一个或多个其他文件的存档,几乎总是被压缩以节省磁盘空间和/或传输时间。在这方面,它们类似于压缩的 tar 存档,即那些通常以 .tar.Z.tar.gz.tgz 结尾的文件,在大多数 Linux ftp 站点和许多 CD-ROM 发行版上都能找到。 zip 文件和 tar 存档之间的一个主要区别是:压缩的 tar 存档将所有文件捆绑在一起,然后将结果作为一个实体压缩;zip 文件压缩单个文件,然后将它们存储在存档中。这种 zip 文件方法在实现最大整体压缩方面效率稍低,但它确实允许您列出存档的内容并在不解压缩整个文件的情况下提取单个文件。

列表

如何实际使用 unzip 来列出存档的内容?最简单的方法是使用 -l 选项(“list”的缩写)

$ unzip -l quake92p.zip
Archive:  quake92p.zip
 Length    Date    Time    Name
 ------    ----    ----    ----
  36064  06-25-96  13:18   DEICE.EXE
 369135  06-27-96  03:51   QUAKE92P.1
   2618  06-27-96  03:34   README.TXT
    177  06-25-96  20:07   INSTALL.BAT
    206  06-27-96  03:54   QUAKE92P.DAT
 ------                    -------
 408200                    5 files

您拥有每个文件的名称(在右侧)、其未压缩的大小以及上次修改的日期和时间。 然而,对于我们中的许多人,尤其是那些长期沉浸在简洁精炼的 ls 命令中的人来说,这有点 过简洁了。对于 ls 的粉丝,或者任何希望了解更多关于存档细节的人来说,unzip 有一种专门用于列出有用和晦涩的 zip 文件信息的完整模式:zipinfo 模式,通过 -Z 选项触发。(在某些系统上,zipinfo 命令作为 unzip 的链接存在,并且与 unzip -Z 同义,但这在撰写本文时对于 Slackware 发行版来说并非如此。)我们将自己限制为描述默认的 zipinfo 列表格式

$ unzip -Z quake92p.zip
Archive:  quake92p.zip   406075 bytes   5 files
-rwxa--     2.0 fat   36064 b- defN 25-Jun-96 13:18 DEICE.EXE
-rw-a--     2.0 fat  369135 b- stor 27-Jun-96 03:51 QUAKE92P.1
-rw-a--     2.0 fat    2618 t- defN 27-Jun-96 03:34 README.TXT
-rwxa--     2.0 fat     177 t- defN 25-Jun-96 20:07 INSTALL.BAT
-rw-a--     2.0 fat     206 t- defN 27-Jun-96 03:54 QUAKE92P.DAT
5 files, 408200 bytes uncompressed, 405569 bytes compressed:  0.6%

您会立即认出它与 ls -l 的输出有某种相似之处。 标题行给出存档名称、其总大小以及其中的文件总数; 尾部给出列出的文件数(在本例中为所有文件)、列出的文件的未压缩和压缩数据总大小(不包括内部 zip 文件头)以及压缩比率。 这里的比率非常差,主要是由于最大的文件 (QUAKE92P.1) 在存储时没有任何压缩。 最左边的列是文件权限。 下一列指示存档器的版本,之后的一列告诉我们文件来自 FAT (DOS) 文件系统。 接下来是未压缩的文件大小和一个列,指示哪些文件最有可能为 binary,哪些文件可能为 text。 接下来的三列注释了每个文件上使用的压缩方法; 时间戳; 和完整的文件名。

提取

现在我们知道了我们有哪些文件,我们如何实际取出这些文件? 文件提取就像输入 unzip 和文件名一样简单

$unzip quake92p
Archive:  quake92p.zip
  inflating: DEICE.EXE
  extracting: QUAKE92P.1
  inflating: README.TXT
  inflating: INSTALL.BAT
  inflating: QUAKE92P.DAT

这里我们省略了 .zip 后缀; unzip 首先查找文件 quake92p,但未找到,然后检查 quake92p.zip。 如果我们只想要 README.TXT 文件怎么办? 没问题。 zip 文件名后的任何内容(好吧,几乎任何内容)都被视为其中包含的文件之一的名称

$unzip quake92p README.TXT
Archive:  quake92p.zip
 inflating: README.TXT

在这里您可能会注意到一个小问题。 如果您现在在 Linux 中使用像 vi 这样的编辑器编辑此文件,您会在每一行的末尾看到类似 ^M 的内容。 或者,如果您使用像 more 这样的分页器查看该文件,您会发现任何被--More--提示符覆盖的行都会立即被擦除。 这些问题是由于 DOS 及其后继者存储文本文件时使用了 两个 行尾字符,即 CR 和 LF(也称为回车符和换行符,或者 ^M 和 ^J,或者 CTRL-M 和 CTRL-J),而不是在所有 Unix 系统上使用的更高效的单字符 (LF)。 因此,当 Unix 实用程序(如编辑器或分页器或编译器)查看 DOS 文本文件时,它的行为可能会有点奇怪,甚至完全崩溃。

幸运的是,有一个简单的解决方案:unzip 的 -a 选项。 最初是 ASCII 转换 的助记符,如今,该选项用于各种文本文件转换。 作为一个单字母选项,它尽力自动转换那些据说是文本的文件,同时保留那些标记为二进制的文件。 要小心! zip 和 PKZIP 在创建存档时并不总是正确猜测,特别是对于某些类别的 MS-Windows 文件,并且 unzip 的“文本”转换 几乎总是不可逆的。 换句话说,不要在进行自动转换的情况下提取,然后在没有首先确保一切正常的情况下删除原始 zip 文件。 但是,unzip 会指示它认为哪些文件在自动转换时是文本

$ unzip -a quake92p
Archive:    quake92p.zip
inflating:  DEICE.EXE               [binary]
extracting: QUAKE92P.1              [binary]
inflating:  README.TXT              [text]
inflating:  INSTALL.BAT             [text]
inflating:  QUAKE92P.DAT            [text]

在这种情况下,一切都按预期工作。 如果由于某种原因,zip 将文本文件标记为二进制文件,并且您想要强制进行文本转换,只需将选项加倍:-aa

但是等等,还有更多! 见多识广的 Linux 用户,很高兴地习惯于文件系统不仅保留文件名的区分大小写,而且还区分仅大小写不同的名称,不会满足于他的目录中的一堆全大写的 DOS 文件名。 输入 -L 选项。 如果(且仅当)文件来自像 DOS FAT 或 VMS 这样的单大小写文件系统,unzip -L 将在提取时将其转换为小写,如下所示

$ unzip -aL quake92p
Archive:  quake92p.zip
  inflating: deice.exe               [binary]
  extracting: quake92p.1             [binary]
  inflating: readme.txt              [text]
  inflating: install.bat             [text]
  inflating: quake92p.dat            [text]

这不是很棒吗?

测试

所以现在您刚刚下载了一大堆 zip 文件,但不想解压缩它们只是为了确保它们没问题。 解决方案是什么? 使用 -t 选项来测试它们

$ unzip -t quake92p
Archive:  quake92p.zip
    testing: DEICE.EXE                OK
    testing: QUAKE92P.1               OK
    testing: README.TXT               OK
    testing: INSTALL.BAT              OK
    testing: QUAKE92P.DAT             OK
No errors detected in compressed data of quake92p.zip.

在这里我们只测试了一个,输出有点过于冗长——我们真正想要的只是每个存档的一行摘要。 unzip 支持 -q 选项以实现不同级别的静默(q 越多,越安静)以及通配符的概念,包括用于内部文件和 zip 文件本身

$ unzip -tq \*.zip
No errors detected in compressed data of arena2b-grr.zip.
No errors detected in compressed data of PngSuite.zip.
No errors detected in compressed data of libgr2-elf-install.zip.
No errors detected in compressed data of ppmz-7.3.zip.
arithc.c                bad CRC e220fe9c  (should be 1c24998c)
At least one error was detected in macm.zip.
No errors detected in compressed data of xfer-zip151.zip.
No errors detected in compressed data of quake091.zip.
No errors detected in compressed data of quake92p.zip.
No errors detected in compressed data of p93b2200.zip.
8 archives were successfully processed.
1 archive had fatal errors.

请注意,通配符 (“*”) 使用反斜杠 (“\”) 转义。 大多数 shell 自己扩展通配符,如果我们允许这样做,unzip 会将命令行视为存档列表; 它会将第一个存档视为 zip 文件名,其余的视为要在第一个存档中测试的文件。 通过转义通配符,我们允许 unzip 执行自己的目录搜索和通配符匹配——顺便说一句,这具有 Unix 风格 正则表达式(非常强大的通配符)不仅可以在 Linux 下使用,而且可以在所有存在 unzip 端口的操作系统下使用,甚至包括普通的旧 DOS。

另一件需要注意的事情是,其中一个存档中存在错误。 可能是传输错误,或者原始文件在创建时可能已损坏; 无论哪种方式,macm.zip 中的文件 arithc.c 可能都无法使用。 尽早知道这些事情总是好的。

此处未涵盖其他一些选项和修饰符; 完整的教程将占用本杂志的大部分篇幅。 幸运的是,unzip 和 zipinfo 的 man 手册(man unzipman zipinfo)包含所有选项的完整列表以及其中许多选项的示例。 不幸的是,Slackware 3.0 及更早版本不包括 zipinfo man 手册。 通过键入 unzip -Z,可以获得 zipinfo 选项的缩写摘要。 同样,只需在不带参数的情况下键入 unzip 即可获得大多数 unzip 选项的摘要。

历史、致谢、指针和未来

unzip、zipinfo、zip 及其同类产品是由 Info-ZIP 组织编写的,这是一个基于 Internet 的奇异生物集合,他们目前散布在地球各地。 鄙人(那是我)是 unzip 和 zipinfo 的主要作者,但实际上有数百人为它们做出了贡献。 最初基于 Samuel H. Smith 的代码,unzip 自那时以来已被完全重写,但默认情况下不再包含一个例程。 然而,我们当然要感谢他让我们陷入困境。 提及 PKWARE 的人员也可能很好,他们的 PKZIP 和 PKUNZIP 程序是世界上大多数源自 DOS 的 zip 文件的来源。 请注意,Info-ZIP 的程序旨在与 PKWARE 的 zip 文件兼容,但它们不是 PKWARE 程序的克隆。(例如,unzip 默认情况下会重新创建存储的 zip 文件目录树,而 PKUNZIP 需要一个特殊选项才能执行此操作。

另请注意,虽然 zip 和 gzip(有时称为“GNU zip”)具有相似的名称、相似的传承——Jean-loup Gailly 和 Mark Adler 是后者的共同作者,并且也是 Info-ZIP 组织的长期成员——以及相同的压缩引擎,但这两种程序基本上是不兼容的。 unzip 和 gunzip 也是如此。 Jean-loup 从未预见到相似性会引起的混乱,而我建议使用显而易见、令人厌恶的替代方案 (feather*) 来更改名称为时已晚。

更严肃地说,当前版本的 unzip 是 5.2,而 5.21 将在您阅读本文时发布。 虽然上面讨论的所有内容在前一个版本 (5.12) 中也同样有效,但有各种新功能和其他改进使 5.2 值得获取。 您可以在 UUNET 的匿名 ftp 站点找到源代码和可执行文件的最新公开发布版本

ftp://ftp.uu.net/pub/archiving/zip/ ftp://ftp.uu.net/pub/archiving/zip/UNIX/LINUX/

您还可以在以下网站找到新闻、历史记录、对某些怪人的描述以及指向世界各地其他 ftp 站点的指针

http://quest.jpl.nasa.gov/Info-ZIP-

Greg Roelofs 从芝加哥大学获得天体物理学学位后逃离,尖叫着逃往硅谷,在那里他现在为 Philips Research 做非常酷的图形和压缩工作。 他于 1990 年春天加入 Info-ZIP,就在该组织成立后不久,在他的黑暗影响下,该组织几乎实现了其完全宇宙重建解体的目标,只缺少一个更好的首字母缩写词才能完成他们的计划。 他也是已知宇宙中最可爱婴儿的父亲。 您可以通过电子邮件 newt@uchicago.edu 或在 Web 上 quest.jpl.nasa.gov/Info-ZIP/people/greg/ 与他联系。

[ ---- 这是一个脚注 ---- ] * 因此 Sunsite 上的所有存档都将是...是的,您猜对了:tar'd 和 feather'd。 哇哈哈哈! 如果可以就好了。

加载 Disqus 评论