gzip命令_Linux gzip命令:压缩和解压文件(.gz文件)

压缩技能,是
Linux 工程师的必修课,它对提升数据传输效率、降低传输带宽、管理备份数据都有着重要的作用。

而在众多的压缩工具中,gzip 算是在开源界里最常用的一款了。下面,我们就来学习 gzip 压缩和解压大法!

gzip 的身世之谜

gzip 的身世其实并不是谜,而是众人皆知的。

在很久以前,UNIX 操作系统上的压缩工具叫作 compress,这个压缩工具采用了很著名的 LZW 压缩算法。但是由于 Unisys 和 IBM 拥有 LZW 压缩算法的专利,所以 UNIX 操作系统不能再随意使用这个算法和这个压缩工具了。为了解决这个问题,Jean-loup Gailly 编写了 gzip 压缩工具,完全替代了有专利争议的 compress 工具,从此 gzip 诞生了。

gzip 工具还被囊括进了 GNU 项目中,成为了其中的一员。

gzip 初体验

gzip 只能针对普通文件(regular file)进行压缩和解压,对于文件夹、符号链接等是不支持的。如果你想把多个文件一起压缩并打包,gzip 自身也是办不到的,需要有它的好兄弟 tar 命令来帮助完成。

下面来演示一下 gzip 单独工作的场景:

#我有一个小视频
[roc@roclinux ruanjian]$ ls -l hero.avi
-rw-rw-r-- 1 roc roc 10627631 2月  19 10:37 hero.avi
 
#用gzip开始压缩, 命令就是这么简单
[roc@roclinux ruanjian]$ gzip hero.avi
 
#压缩后, 原文件消失, 出现一个以.gz后缀的新文件, 大小变小了(虽然不多)
#如果压缩的是文本文件, 效果会很明显
[roc@roclinux ruanjian]$ ls -l hero.avi.gz
-rw-rw-r-- 1 roc roc 10605586 2月  19 10:37 hero.avi.gz
 
#我们再解压回来, 只需加-d选项即可
[roc@roclinux ruanjian]$ gzip -d hero.avi.gz
 
#完璧归赵啦
[roc@roclinux ruanjian]$ ls -l hero.avi
-rw-rw-r-- 1 roc roc 10627631 2月  19 10:37 hero.avi
 
#如果想在压缩后, 保留原文件, 那么可以用-c选项实现
#-c选项就是让gzip把压缩的内容输出到标准输出, 而非写入到文件中
[roc@roclinux ruanjian]$ gzip -c hero.avi > hero.avi.gz

虽然 gzip 可以单独工作,但其实平时大家并不总是这么用,最常用的方式还是结合 tar 命令一起来用。我们继续往下看。

gzip 的代言人是 tar

虽然 gzip 常用,但 gzip 性格有些低调,通常是隐藏在 tar 打包工具的背后,为用户默默地提供着压缩服务。

这是因为在实际生产环境中,我们遇到的情况通常不是只针对一个文件进行压缩,而是针对多个文件和文件夹一起打包并压缩。而 tar 就是用来打包用的,所以它自然而然就成了各个压缩工具的代言人了。

有些同学可能会问,“打包/拆包”“压缩/解压缩”有什么区别?我们用一个生活中的例子来解释,相信大家会豁然开朗:

  • 就像搬家时,我们把每一床棉被都抽成真空,这叫作压缩,然后把好几床抽真空的棉被用绳子捆绑起来,这就叫打包。
  • 东西搬到新家后,把绳子解开,就是拆包,然后把每床棉被舒展开,让棉被松软起来,这就是解压缩。
  • 如果不抽真空,只是把几床棉被简单地用绳子捆起来,那么就单独用tar就好了。
  • 如果只有一床棉被,打算抽真空,那么就用gzip就好了。
  • 如果有好多床棉被,既要抽真空,又要捆起来,那么就要将tar和gzip结合起来使用。

来看看如何拆包解压

在日常的工作中,拆包解压,绝对要比压缩打包的次数多得多。比如我们下载了一个开源软件之后:

#这是我们下载的开源软件包, 大小是3.4MB
[roc@roclinux ruanjian]$ ls -hl curl-7.34.0.tar.gz
-rw-rw-r-- 1 roc roc 3.4M 2月  17 22:52 curl-7.34.0.tar.gz
 
#我们解压并拆包, 使用了tar -xzvf这样的命令用法
#下面输出的以curl-7.34.0/开头的好多行, 都是拆包和解压的过程
[roc@roclinux ruanjian]$ tar -xzvf curl-7.34.0.tar.gz
curl-7.34.0/
curl-7.34.0/depcomp
curl-7.34.0/mkinstalldirs
curl-7.34.0/docs/
curl-7.34.0/docs/VERSIONS
curl-7.34.0/docs/MAIL-ETIQUETTE
curl-7.34.0/docs/BINDINGS
curl-7.34.0/docs/LIBCURL-STRUCTS
curl-7.34.0/docs/BUGS
curl-7.34.0/docs/libcurl/
curl-7.34.0/docs/libcurl/curl_share_init.3
curl-7.34.0/docs/libcurl/libcurl.3
curl-7.34.0/docs/libcurl/curl_share_strerror.3
curl-7.34.0/docs/libcurl/curl_free.pdf
curl-7.34.0/docs/libcurl/curl_easy_send.html
curl-7.34.0/docs/libcurl/curl_easy_reset.3
(此处省略数百行)
 
#解压后, 我们来对比一下解压前后的大小变化。前面说过, 对于文本或代码类的文件, 压缩的效果会非常明显。
[roc@roclinux ruanjian]$ du -sh curl-7.34.0 curl-7.34.0.tar.gz
20M     curl-7.34.0
3.4M    curl-7.34.0.tar.gz
 
#进入到解压后的文件夹中
[roc@roclinux ruanjian]$ cd curl-7.34.0/
 
#这就是拆包解压后的内容啦
[roc@roclinux curl-7.34.0]$ ls -F
acinclude.m4  CMakeLists.txt  configure.ac    include/       m4/                maketgz*        RELEASE-NOTES
aclocal.m4    compile*        COPYING         install-sh*    MacOSX-Framework*  missing*        src/
buildconf*    config.guess*   curl-config.in  lib/           Makefile          
mkinstalldirs*  tests/
CHANGES       config.sub*     depcomp*        libcurl.pc.in  Makefile.am        packages/       vs/
CMake/        configure*      docs/           ltmain.sh      Makefile.in        README          winbuild/

下面我们回过头来详细介绍一下上面这段例子中的知识点。

首先,在 Linux 的世界里,当我们看到文件后缀是 .tar.gz 或者 .tgz 时,心里应该默念“这是用 gzip 压缩的打包文件”。对于这类文件,我们是可以通过 gzip 来解压的。本例中的 curl-7.34.0.tar.gz 就属于这类。

其次,解压时我们用到了 tar-xzvf 这样复杂晦涩的选项组合,下面来逐一解读一下:

  • -x选项:表示要进行拆包动作。
  • -z选项:表示用 gzip 进行压缩或解压缩。如果同时使用了 -x 选项,则表示解压。如果使用了 -c 选项,则表示压缩。
  • -v选项:表示在拆包过程中直播整个过程,把已拆包的文件显示出来。
  • -f选项:表示指定要拆包的文件(注意,这个选项一定要放在各个选项的最后,也就是要和所指定的文件名挨得最近)。

如果你是第一次看到 -xzvf 选项组合,可能会觉得晦涩难记,没关系,多用几次就熟了。我现在手指早已形成了肌肉记忆了。(不知道是该笑还是该哭……)

tar.gz 文件是怎么造出来的

我们已经练就了“解压大法”,接下来,就要学习怎么创建解压文件了。如果你掌握了刚才所讲的内容,那么创建压缩文件也并非难事。

[roc@roclinux ruanjian]$ tar -czvf mygzipfile.tar.gz curl-7.34.0
curl-7.34.0/
curl-7.34.0/winbuild/
curl-7.34.0/winbuild/gen_resp_file.bat
curl-7.34.0/winbuild/MakefileBuild.vc
curl-7.34.0/winbuild/Makefile.msvc.names
curl-7.34.0/winbuild/BUILD.WINDOWS.txt
curl-7.34.0/winbuild/Makefile.vc
curl-7.34.0/config.guess
curl-7.34.0/Makefile.in
curl-7.34.0/CHANGES
curl-7.34.0/ltmain.sh
(此处省略数百行)
 
#看!我们的tar.gz文件已经新鲜出炉了
[roc@roclinux ruanjian]$ ls -l mygzipfile.tar.gz
-rw-rw-r-- 1 roc roc 3567446 2月  19 15:45 mygzipfile.tar.gz

细心观察的话,你会发现打包压缩所用的命令是 tar-czvf,和拆包解压的 -xzvf 非常相似,只是 x 替换成了 c 而已。

  • -c选项:表示要进行打包动作。
  • -z选项:表示用 gzip 进行压缩或解压缩。如果同时使用了 -x 选项,则表示解压。如果使用了 -c 选项,则表示压缩。
  • -v选项:表示在打包过程中直播整个过程,把已打包的文件显示出来。
  • -f选项:表示指定要打包的文件,完全可以指定多个,文件夹和文件都可以。

不想解压,只想看看

有些时候,我们不确定“葫芦里装的什么药”,所以不想直接解压,只想看看里面包括了哪些文件。这时,我们用 tar 命令就可以做到:

[roc@roclinux ruanjian]$ tar -ztvf curl-7.34.0.tar.gz
drwxr-xr-x 1000/1000         0 2013-12-17 15:51 curl-7.34.0/
-rwxr-xr-x 1000/1000     23566 2013-11-11 15:47 curl-7.34.0/depcomp
-rwxr-xr-x 1000/1000     3538 2013-09-09 06:11 curl-7.34.0/mkinstalldirs
drwxr-xr-x 1000/1000         0 2013-12-17 15:51 curl-7.34.0/docs/
-rw-r--r-- 1000/1000    114456 2013-12-17 06:02 curl-7.34.0/lib/http.c
(此处省略数百行)

我们使用了 -ztvf 选项实现了“只想看看”的效果,其中少了 -x 选项,却多了 -t 选项:

  • 少了-x选项:因为我们并不想实际拆包,所以一定要去掉 -x 选项。
  • 多了-t选项:-t 选项的作用是列出打包文件中的内容,正好符合我们的需求。

有针对性地解压某个文件

通过查看 tar.gz 文件中的内容,我们知道了 curl 软件包中有一个 http.c 文件。现在我想提取出 curl-7.34.0/lib/http.c 这个文件,看看它的源码,但是又不想把这个软件压缩包全部解压,该怎么做呢?即我们如何从一个打包压缩的 tar.gz 文件中提取出某一个单独的文件呢?方法总比问题多,揭晓答案:

#原来就在拆包解压命令的后面直接加上要提取的文件全路径就好了, 简单!
[roc@roclinux ruanjian]$ tar -xzvf curl-7.34.0.tar.gz
curl-7.34.0/lib/http.c
curl-7.34.0/lib/http.c
 
#看, 这就是我们单独提取出来的文件
[roc@roclinux ruanjian]$ tree curl-7.34.0
curl-7.34.0
`-- lib
    `-- http.c
 
1 directory, 1 file

压缩速度与压缩强度

有些人追求压缩的速度,希望快点完成压缩;而有些人却更追求压缩的强度,希望把东西压缩得越小越好。

gzip 命令确实为用户提供了这样的选择权,包含了九个压缩级别,分别是 1、2、3、4、5、6、7、8、9:

  • “1 级”表示压缩速度最快,但强度不高。
  • “9 级”表示压缩强度最高,但速度较慢。
  • 默认情况下是 6 级。

我们来实战一下。

#这是我们的压缩对象, 一个足有1.7GB大小的日志文件, 它是一个实实在在的纯文本文件
[roc@roclinux ruanjian]$ ls -hl error.log
-rw-r--r-- 1 roc roc 1.7G 2月  20 14:39 error.log
 
#我们先用“最快速”的压缩等级(1级), 同时使用time来精准计时
[roc@roclinux ruanjian]$ time gzip -1 error.log
 
real    0m22.322s
user    0m20.983s
sys     0m1.250s
 
#“最快速”压缩等级, 耗时是22.3秒, 压缩后的大小为99MB
[roc@roclinux ruanjian]$ ls -hl error.log.gz
-rw-r--r-- 1 roc roc 99M 2月  20 14:39 error.log.gz
 
#然后我们再尝试“最强”压缩等级(9级), 同样也使用time来精准计时
[roc@roclinux ruanjian]$ time gzip -9 error.log
 
real    1m3.544s
user    1m2.189s
sys     0m1.256s
 
#“最强”压缩等级, 耗时变长了许多, 为1分3秒, 但压缩后的文件却是更小了, 为70MB
[roc@roclinux ruanjian]$ ls -hl error.log.gz
-rw-r--r-- 1 roc roc 70M 2月  20 14:39 error.log.gz

等级数字不好记的话,可以这样记:1 表示一步到位,往往一步到位的东西追求的是快,而不是精致程度。

好了,gzip 命令就讲到这里啦,内容较多,足够大家消化一两天了。

点赞