# 压缩与解压缩

## 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)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://kerasnoone.gitbook.io/garnet/gong-cheng-zhan/linux/chang-yong-gong-neng/ya-suo-yu-jie-ya-suo.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
