> For the complete documentation index, see [llms.txt](https://kerasnoone.gitbook.io/garnet/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kerasnoone.gitbook.io/garnet/gong-cheng-zhan/linux/chang-yong-gong-neng/ya-suo-yu-jie-ya-suo.md).

# 压缩与解压缩

## zip格式

### 压缩

将当前目录下的所有文件和文件夹压缩至一个文件中. 要特别注意其中的`-r`参数, 否则只会打包指定目录第一层中的内容, 不会深入到子目录中的文件.

```bash
zip -r package.zip ./*
```

**压缩时排除文件**

将目录中除去`*.xlsx`之外的文件打包:

```bash
zip -r package.zip ./* -x ./*.xlsx
```

排除多个文件

```bash
zip -r package.zip ./* -x "./1.xlsx" -x "./2.xlsx"
```

排除一个子目录下的所有内容

```bash
zip -r package.zip ./* -x "./models/*"
```

**常用参数**:

* `-r`: 递归处理, 将指定目录下的所有文件和子目录一并处理
* `-x`: 压缩时排除文件列表中的文件, 后面紧跟要排除的文件

[Linux zip命令](https://m.runoob.com/linux/linux-comm-zip.html)

### 解压缩

解压到当前目录：

```bash
unzip something.zip
```

解压到指定目录

```bash
unzip -d /path/to/dir something.zip
```

**常用参数**:

* `-d`: 指定文件解压后存储的目录
* `-l`: 显示压缩文件内所包含的文件

## tar格式

tar指令提供打包/解包, 压缩/解压缩的功能.

* `-c`: 建立一个打包/压缩文件, 这个文件可以只打包不压缩, 也可以打包+压缩
* `-x`: 解开一个包文件, 如果这个包文件是压缩过的, 还需要使用`-z`或`-j`参数指明压缩格式
* `-t`: 查看包内的文件

这三个指令同时只能使用一个, 不能共同使用.

**压缩格式**

如果需要压缩/解压, 需要制定压缩格式. tar支持的压缩格式有三种:

* `-z`: 打包文件是否同时具有gz属性, 是否需要用gzip压缩
* `-j`: 打包文件是否同时具有bz2属性, 是否需要用bzip2压缩
* `-J`: 打包文件是否同时具有xz属性, 是否需要用xz压缩

**常用指令**

* `-v`: 过程中显示压缩或者打包的内容
* `-f`: 使用的打包文件的文件名. `-f`参数在使用的时候一定排在其他参数的后面, 后面紧接文件名

### 打包/压缩

**只打包, 不压缩**

将指定文件打包至同一文件中.

```bash
tar -cvf package.tar /path/to/data1.csv /path/to/data2.txt
```

将当前目录下所有文件打包至一个文件中.

```bash
tar -cvf package.tar ./*
```

**打包+压缩**

打包并用`gzip`格式压缩.

```bash
tar -czvf package.tar.gz ./*
```

**排除指定文件**

排除一个文件

```bash
tar -czvf package.tar.gz --exclude=/path/to/file  ./*
```

排除指定目录, 注意跟`zip`指令的区别.

```bash
tar -czvf package.tar.gz --exclude=models  ./*
```

排除多个目录, 需要连用多个`--exclude`参数

```bash
tar -czvf package.tar.gz --exclude=models --exclude=venv  ./*
```

### 解包/解压缩

解压gz文件到当前目录.

```bash
tar -xzvf package.tar.gz
```

解包到指定目录.

```bash
tar -xvf package.tar -C /path/to/save
```

**常用参数**

* `-C`: 切换到指定目录, 表示指定解压缩包的内容和打包的内容存放的目录

### 分卷

有时候会遇到文件大小的限制. 这时候除了压缩外, 还需要分卷, 控制每个分卷文件的大小.

**压缩**

首先进行正常的压缩:

```bash
tar -zcvf hello.tar.gz hello
```

然后对压缩后的文件进行分割:

```bash
split -b 100M -d -a 1 hello.tar.gz hello.tar.gz.
```

`split`的参数意义如下:

* `-b`, `--bytes=SIZE`: 指定每个分割文件的大小, 单位有K, M, G, P等
* `-d`, `--numeric-suffixes`: 指定分割文件的后缀为数字
* `-a`, `--suffix-length=N`: 指定分割文件数字后缀的长度, 如果是1, 后缀为0,1,2...; 如果是2, 则为00,01,02...; 默认是2

得到如下的多个子压缩文件:

```
-rw-r--r-- 1 root root 104857600 Dec 25 16:54 hello.tar.gz.0
-rw-r--r-- 1 root root 104857600 Dec 25 16:54 hello.tar.gz.1
-rw-r--r-- 1 root root 104857600 Dec 25 16:54 hello.tar.gz.2
-rw-r--r-- 1 root root 104857600 Dec 25 16:54 hello.tar.gz.3
-rw-r--r-- 1 root root 104857600 Dec 25 16:55 hello.tar.gz.4
-rw-r--r-- 1 root root 104857600 Dec 25 16:55 hello.tar.gz.5
-rw-r--r-- 1 root root 104857600 Dec 25 16:55 hello.tar.gz.6
-rw-r--r-- 1 root root  19020093 Dec 25 16:55 hello.tar.gz.7
```

也可以使用管道的方法, 将上面两个指令连在一起. 如果用管道, tar的指令就不用先生成一个大文件了, 更方便:

```bash
tar -zcvf - hello | split -b 100M -d -a 1 - hello.tar.gz.
```

**解压缩**

```bash
cat hello.tar.gz.* | tar -zxv
```

**参考资料**

* [Linux中使用tar命令进行分卷压缩](https://blog.csdn.net/gxd520/article/details/93880695)
* [linux 分卷压缩命令](https://www.cnblogs.com/wzzkaifa/p/7259432.html)
