11-打包压缩

基本知识

背景知识

我们知道在Windows下最常见的压缩文件就只有两种,一是,zip,另一个是.rar。可是Linux就不同 了。在Linux的环境中,压缩文件的扩展名大多是:『.tar, .tar.gz, .tgz, .gz, .Z, .bz2』。

我们知道在Linux中扩展名并没有什么用,但之所以仍然要使用扩展名是因为 Linux 支持的压缩命令非常多,且不同的命令所用的压缩技术并不相同,当然彼此之间可能就无法互通压缩/解压缩文件。所以,当你下载到某个压缩档时,自然就需要知道该文件是由哪种压缩命令所制作出来的,好用来对照著解压缩啊。

也就是说,虽然 Linux 文件的属性基本上是与档名没有绝对关系的, 但是为了方便助记,适当的扩展名还是必要的!

常见的后缀如下:

1
2
3
4
5
6
*.Z         compress 程序压缩的文件;
*.gz gzip 程序压缩的文件;
*.bz2 bzip2 程序压缩的文件;
*.tar tar 程序打包的数据,并没有压缩过;
*.tar.gz tar 程序打包的文件,其中并且经过 gzip 的压缩
*.tar.bz2 tar 程序打包的文件,其中并且经过 bzip2 的压缩

Linux上常见的压缩命令就是 gzip 与 bzip2 ,至于compress 已经落伍了。两个压缩命令中bzip2 命令的压缩比更好

压缩率(Compression ratio),描述压缩文件的效果名,是文件压缩后的大小与压缩前的大小之比,例如:把100m的文件压缩后是90m,压缩率为90/100100%=90%,压缩率一般是越小越好,但是压得越小,解压时间越长

打包与压缩的区别

  • 打包

    指将一大堆文件或目录什么的变成一个总的文件

  • 压缩

    将一个大的文件通过一些压缩算法变成一个小文件

为什么要区分这 两个概念呢?其实这源于Linux中的很多压缩程序只能针对一个文件进行压缩,这样当你想要压缩一大堆文件时,你就得先借助另外的工具将这一大堆文件先打 成一个包,然后再就原来的压缩程序进行压缩

常用压缩命令

gzip

压缩为.gz文件

1
2
3
4
5
6
7
8
9
10
11
12
zuo@zuo-VirtualBox:~/Sample/Temp$ gzip -h
Usage: gzip [OPTION]... [FILE]...
# 注意这个 in-place
Compress or uncompress FILEs (by default, compress FILES in-place).

-c, --stdout 保留输入文件,将压缩的数据输出到萤幕上,可透过数据流重导向来处理
-d, --decompress 解压
-k, --keep 保留输入文件
-r, --recursive 递归压缩
-v, --verbose verbose 显示每个文件的名子和压缩率
-1, --fast 让压缩更快
-9, --best 让压缩效果更好

首先要说明几点:

  1. 默认情况下压缩文件会替换源文件,解决办法有两种
    1. 使用-k参数
    2. 使用-c参数并重定向,好处是可以自定义名字
  2. -r指的是将路径内所有文件压缩,而不是压缩整个路径
  3. -1~-9指的是压缩等级,-1 最快,但是压缩比最差;-9 最慢,但是压缩比最好。默认是 -6
  4. 使用-d参数可以解压缩,也可以使用gunzip来解压
  5. 使用-c参数可以预览内容,不过要预览压缩文件内容需要使用-dc

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 两个文件,一个目录
zuo@zuo-VirtualBox:~/Sample/Temp$ ls
1.txt 2.txt Dir
zuo@zuo-VirtualBox:~/Sample/Temp$ gzip 1.txt
zuo@zuo-VirtualBox:~/Sample/Temp$ gzip -k 2.txt
# 1.txt被替换了,2.txt没有
zuo@zuo-VirtualBox:~/Sample/Temp$ ls
1.txt.gz 2.txt 2.txt.gz Dir
# 对1.txt.gz解压,1.txt.gz被替换为1.txt
zuo@zuo-VirtualBox:~/Sample/Temp$ gzip -d 1.txt.gz
zuo@zuo-VirtualBox:~/Sample/Temp$ ls
1.txt 2.txt 2.txt.gz Dir
# 对1.txt压缩并重定向为1.gz
zuo@zuo-VirtualBox:~/Sample/Temp$ gzip -c 1.txt > 1.gz
zuo@zuo-VirtualBox:~/Sample/Temp$ ls
1.gz 1.txt 2.txt 2.txt.gz Dir

zuo@zuo-VirtualBox:~/Sample/Temp$ cd Dir; ls
file1 file2 file3
# 递归压缩目录中的文件并显示信息,模式为1级
zuo@zuo-VirtualBox:~/Sample/Temp/Dir$ gzip -kv1r ./
.//file3: 0.0% -- replaced with .//file3.gz
.//file1: 0.0% -- replaced with .//file1.gz
.//file2: 0.0% -- replaced with .//file2.gz
zuo@zuo-VirtualBox:~/Sample/Temp/Dir$ ls
file1 file1.gz file2 file2.gz file3 file3.gz

bzip2

若说 gzip 是为了取代 compress 并提供更好的压缩比而成立的,那么bzip2 则是为了取代 gzip 并提供更佳的压缩比而来的

它的压缩比比 gzip 还要好,更重要的是 bzip2的用法几乎与 gzip 相同 。只是会把文件压缩为.bz2文件。

1
2
3
4
5
6
7
8
9
10
zuo@zuo-VirtualBox:~/Sample/Temp$ ls
1.txt 2.txt Dir
# 压缩
zuo@zuo-VirtualBox:~/Sample/Temp$ bzip2 -k 1.txt
# 压缩为.bz2文件
zuo@zuo-VirtualBox:~/Sample/Temp$ ls
1.txt 1.txt.bz2 2.txt Dir
# 预览解压后的文件(但不解压),实际上是将解压后的数据重定向到屏幕上
zuo@zuo-VirtualBox:~/Sample/Temp$ bzip2 -dc 1.txt.bz2
This is a file

也可以使用bunzip2来进行解压

打包命令 tar

前一小节谈到的命令大多仅能针对单一文件来进行压缩,虽然 gzip 与 bzip2 也能够针对目录来进行压缩,不过,这两个命令对目录的压缩指的是将目录内的所有文件 "分别" 进行压缩的动作,而不像在 Windows 的系统,可以使用类似 WinRAR 这一类的压缩软件来将好多数据包成一个文件的样式。

这种将多个文件或目录包成一个大文件的命令功能,我们可以称呼他是一种打包命令。Linux 的打包命令是tar命令。tar 可以将多个目录或文件打包成一个大文件,同时还可以透过 gzip/bzip2 的支持,将该文件同时进行压缩

目前 Windows 的 WinRAR 也支持 .tar.gz 档名的解压缩。

使用方式

tar的压缩用法比较复杂,因此我们只简单的示例一下用法:

  • 压 缩:tar -[j|z]cv -f filename.tar.bz2 <要被压缩的文件或目录名称>
  • 查 询:tar -[j|z]tv -f filename.tar.bz2
  • 解压缩:tar -[j|z]xv -f filename.tar.bz2 -C <欲解压缩的目录>

参数解释:

1
2
3
4
5
6
7
8
9
-c, --create  		:创建打包文件,可搭配 -v 来察看过程中被打包的档名(filename)
-t, --list :察看打包文件的内容含有哪些档名,重点在察看档名就是了;
-x, --extract :解打包或解压缩的功能,可以搭配 -C (大写) 在特定目录解开
特别留意的是, -c, -t, -x 不可同时出现在一串命令列中。
-j :透过 bzip2 的支持进行压缩/解压缩:此时档名最好为 *.tar.bz2
-z :透过 gzip 的支持进行压缩/解压缩:此时档名最好为 *.tar.gz
-v :在压缩/解压缩的过程中,将正在处理的档名显示出来!
-f filename :-f 后面要立刻接要被处理的档名!建议 -f 单独写一个选项罗!
-C Dir :这个选项用在解压缩,若要在特定目录解压缩,可以使用这个选项。

注意一下-f filename这个参数,这是我们自己取的档名,因为tar 并不会主动的产生创建的文件名,所以我们必须自定义!

也正因如此,扩展名就显的很重要了!

  • 如果不加 [-j|-z] 的话,档名最好取为 *.tar 即可
  • 如果是 -j 选项,代表有bzip2 的支持,因此档名最好就取为 *.tar.bz2
  • 如果是 -z 选项,代表有gzip 的支持,因此档名最好就取为 *.tar.gz

## 使用示例

下面给出使用的例子,首先我们看一下当前目录的情况:

1
2
3
4
5
6
7
8
9
zuo@zuo-VirtualBox:~/Sample/Temp$ tree
.
├── 1.txt
├── 2.txt
└── Dir
├── file1
└── file2

1 directory, 4 files

首先只打包看看

1
2
3
4
5
6
7
8
9
10
11
12
13
# 打包目录
zuo@zuo-VirtualBox:~/Sample/Temp$ tar -c -f Dir.tar Dir/
zuo@zuo-VirtualBox:~/Sample/Temp$ ls
1.txt 2.txt Dir Dir.tar
# 查看
zuo@zuo-VirtualBox:~/Sample/Temp$ tar -t -f Dir.tar
Dir/
Dir/file1
Dir/file2
# 打包多个文件
zuo@zuo-VirtualBox:~/Sample/Temp$ tar -c -f txt.tar 1.txt 2.txt
zuo@zuo-VirtualBox:~/Sample/Temp$ ls
1.txt 2.txt Dir Dir.tar txt.tar

需要注意的是,-c -f可以写成-cf但不能写出-fc,否则会报错

1
2
3
zuo@zuo-VirtualBox:~/Sample/Temp$ tar -fc Dir.tar Dir/ 
tar: 您必须从"-Acdtrux", "--delete"或是"--test-label"中指定一个选项
请用“tar --help”或“tar --usage”获得更多信息。

所以为了逻辑清晰,建议将-f单独列开

然后试一下压缩,我们使用gzip,也就是参数-z

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 压缩
zuo@zuo-VirtualBox:~/Sample/Temp$ tar -cz -f Dir.tar.gz Dir/
zuo@zuo-VirtualBox:~/Sample/Temp$ ls
1.txt 2.txt Dir Dir.tar Dir.tar.gz
# 查看
zuo@zuo-VirtualBox:~/Sample/Temp$ tar -tzv -f Dir.tar.gz
drwxr-xr-x zuo/zuo 0 2018-09-30 00:00 Dir/
-rw-r--r-- zuo/zuo 0 2018-09-29 23:42 Dir/file1
-rw-r--r-- zuo/zuo 0 2018-09-30 00:00 Dir/file2
# 解压到 ./Dir目录下
zuo@zuo-VirtualBox:~/Sample/Temp$ tar -xz -f Dir.tar.gz -C ./Dir
zuo@zuo-VirtualBox:~/Sample/Temp$ tree
.
├── 1.txt
├── 2.txt
├── Dir
│   ├── Dir
│   │   ├── file1
│   │   └── file2
│   ├── file1
│   └── file2
├── Dir.tar
└── Dir.tar.gz

2 directories, 8 files