# 压缩文件

# tar

:一种打包文件的格式,不会进行压缩,扩展名为 .tar 。

  • tar 命令也支持使用 gzip、bzip2、xz 压缩格式。
  • 打包命令:
    tar -cf <name>.tar <path>...          # 将指定文件或目录打包
        -c                                # 创建一个新文件
        -x                                # 提取文件。能根据文件头部的内容识别出 gzip、bzip2、xz 压缩格式,并自动解压
        -v                                # 显示处理过程的具体信息
        -f <name>.tar                     # 使用归档文件
        --exclude=./log*                  # 根据路径 pattern 将一些文件排除打包
        -g <snapshot>                     # 进行增量打包,生成一个快照文件
    
    • 打包文件时,如果输入的原路径是绝对路径,则会按绝对路径打包,生成多余的多层目录。因此,建议输入相对路径。
    • 如果已存在同名的包文件,则会覆盖它。
  • 解包命令:
    tar
        -xv <name>.tar                    # 解包到当前目录
              -C <dir>                    # 解包到指定目录(该目录必须已存在)
              [path]...                   # 只解压指定路径的文件(可以使用通配符)
              -p                          # 保留文件的原访问权限,否则将解压后文件的所有者变为当前用户。root 用户默认会启用该选项
        -tf <name>.tar                    # 不解包,只显示其中的文件列表。用 less xx.tar 命令也能查看文件列表
        -tf <name>.tar.gz | xargs rm -rf  # 删除解包生成的文件
    
  • 增量打包的示例:
    mkdir logs
    tar -g logs-snapshot -cvf logs-full-backup.tar logs/             # 先全量打包,作为起点
    touch logs/f1
    tar -g logs-snapshot -cvf logs-incremental-backup-1.tar logs/    # 增量打包
    touch logs/f2
    tar -g logs-snapshot -cvf logs-incremental-backup-2.tar logs/    # 增量打包
    
    • 用 -g 选项进行增量打包时,会在快照文件中记录此时打包的所有文件的 Modify time 。
      • 下一次增量打包时,如果有新增文件,或者老文件的 Modify time 更新了,才加入打包,否则生成的增量包为空。
      • 多次增量打包时,注意生成的 .tar.gz 包名不能重复,否则会覆盖之前的增量包。
      • 缺点:增量打包时,不能记录被删除的老文件。
    • 解包时,先解压全量包,然后依次解压各个增量包:
      tar -xvf logs-full-backup.tar
      tar -xvf logs-incremental-backup-1.tar
      tar -xvf logs-incremental-backup-2.tar
      

# gzip

:一种压缩文件格式,基于 Deflate 算法,扩展名为 .gz 。

  • 压缩命令:
    tar -zcvf <name>.tar.gz <path>...
        -z                              # 采用 gzip 格式
    
    • 压缩 tar 包时的扩展名为 .tar.gz ,可简写为 .tgz 。
  • 解压命令:
    tar -xf <archive>
    

# bzip2

:一种压缩文件格式,基于 Burrows–Wheeler 算法,扩展名为 .bz2 。

  • 安装:
    yum install bzip2
    
  • 命令:
    bzip2 <file>...
        -c            # --stdout ,将压缩或解压的文件输出到 stdout
        -z            # --compress ,压缩
        -d            # --decompress ,解压
        -k            # --keep ,在压缩、解压成功之后保留输入文件。默认会删除
    
    • bzip2 命令只支持压缩单个文件,因此通常用 tar 命令打包后压缩。默认将压缩后文件命名为 <name>.bz2
  • 压缩命令:
    tar -jcvf <name>.tar.bz2 <path>...
        -j            # 采用 bzip2 格式
    
  • 解压命令:
    tar -xf <archive>
    

# pbzip2

:一个命令行工具,以多线程方式进行 bzip2 压缩、解压。

  • 它会将文件数据划分为多个块,通过多线程并发处理。
  • 安装:
    yum install pbzip2
    
  • 压缩命令:
    tar -c <path> | pbzip2 -zk -p2 > <name>.tar.bz2
                          -b <int>    # 数据块的大小,单位为 100KB 。默认为 9 ,即 900KB
                          -m <int>    # 最多使用的内存量,单位为 MB 。默认为 100 ,即 100MB
                          -p <int>    # 使用的 CPU 数,即创建的线程数。默认会使用全部 CPU 核数
    
    • pbzip2 命令只支持压缩单个文件,且默认将压缩后文件输出到 stdout 。
  • 解压命令:
    pbzip2 -cdk -p2 <name>.tar.bz2  | tar -x
    

# xz

:一种压缩文件格式,基于 LZMA 算法,扩展名为 .xz 。

  • xz 命令与 bzip2 命令的用法相似。
  • 压缩命令:
    tar -Jcvf <name>.tar.xz <path>...
        -J          # 采用 xz 格式
    
  • 解压命令:
    tar -xf <archive>
    

# zip

:一种压缩文件格式,扩展名为 .zip 。

  • 支持多种压缩算法:

    • Deflate :Zip、GZip 的默认压缩算法,对应的解压算法称为 Inflate 。压缩率一般,但压缩、解压快。
    • Burrows–Wheeler :压缩率高,一般能压缩文件体积到 20% ,但压缩、解压慢。
    • LZMA :xz、7-Zip 的默认压缩算法,压缩率更高。
  • 安装:

    yum install zip
    
  • 压缩命令:

    zip <name>.zip <path>     # 压缩文件
          -r                  # 递归处理目录
          -y                  # --symlinks ,直接压缩软链接文件。否则默认会压缩它指向的目标文件
          -s 500m             # --split-size ,将压缩包分割成多份,并设置每份的最大体积
          -i "*.py"           # --include ,只打包路径与 pattern 匹配的文件。注意 pattern 要用引号包住,避免先执行 * 去匹配文件名
          -x "logs/*" "*.log" # --exclude ,将一些文件排除打包。--exclude 比 --include 的优先级更高
          -q                  # 安静模式,不显示过程信息
          -P "***"            # 设置密码
    
    • 如果已存在同名的压缩包,则会加入其中。
      • 如果该压缩包中已存在同名的文件,则会覆盖它。
    • 例:批量压缩文件
      file_list=`ls *.mp4`
      for f in $file_list
      do
          zip $f.zip $f -P '***'
          rm -f $f
      done
      
  • 解压命令:

    unzip <name>.zip          # 解压一个压缩包
            [path]...         # 只解压指定路径的文件(可以使用通配符)
            -d <dir>          # 解压到指定目录(默认是当前目录)
            -o                # 当解压后的文件已存在时,直接覆盖
            -q                # 安静模式,不显示过程信息
    
            -l                # 不解压,而是显示其中的文件列表、修改时间。用 less xx.zip 命令也能查看文件列表
            -Z                # Zipinfo ,显示压缩包的详细信息,包括文件列表、模式、大小等
            -Z1               # 只显示文件列表
    
    • unzip 命令不支持直接解压分割成多份的压缩包。
      比如生成分割的压缩包:
      zip -s 10m -r tmp.zip /tmp    # 假设此时生成 tmp.z01  tmp.z02  tmp.zip ,其中 tmp.zip 是最后一份压缩包
      
      此时执行 unzip tmp.zip 会报错 bad zipfile offset ,需要用以下命令解压:
      zip -F tmp.zip --out tmp-fixd.zip   # 修复分割的压缩包,合并成一个包
      unzip tmp-fixd.zip
      

# 7-Zip

:一种压缩文件格式,扩展名为 .7z 。

  • 压缩算法默认采用 LZMA ,压缩率很高。
  • 支持给压缩包设置密码,加密其内容。
    • Zip 采用传统的 ZipCrypto 加密算法,存在漏洞:如果知道文件中 12 bytes 的明文,则能大幅降低暴力破解的计算量。
    • 7-Zip 采用 AES-256 加密算法,很安全,且支持将文件名也加密。
  • 7z 格式不能用于备份文件,因为它不会保留文件的 owner、group 信息。
  • 安装:
    yum install p7zip p7zip-plugins
    
  • 命令:
    7z <name>.7z [path]
          # 关于压缩
          a               # 将本机指定 path 的文件加入压缩包,会递归处理目录
          d               # 删除压缩包中指定 path 的文件
          -p"***"         # 设置密码
          -mhe=on         # 将文件名也加密
    
          # 关于解压
          x               # 解压压缩包中的文件。默认会提取所有文件,可以只提取指定 path 的文件
          l               # 不解压,而是显示其中的文件列表
    
  • 例:
    7z a logs.7z logs/    # 压缩
    7z x logs.7z          # 解压