Linux bzip2命令

功能说明:bzip2命令用于使用Burrows-Wheeler算法压缩和解压缩文件,产生.bz2格式的压缩文件。它以高压缩率著称,特别适合压缩文本文件,是Linux系统中最常用的压缩工具之一。
主要功能
  • 压缩文件为.bz2格式
  • 解压.bz2压缩文件
  • 多种压缩级别选择(1-9)
  • 测试压缩文件完整性
  • 保留原始文件(可选)
  • 多文件批量处理
算法特点
  • 基于Burrows-Wheeler变换
  • 使用霍夫曼编码
  • 块大小为100-900KB
  • 压缩率高,但速度较慢
  • 适合文本文件和源代码
  • 开源且广泛使用

命令语法

语法格式
bzip2 [选项] [文件名...]

命令参数

参数 说明
-1 到 -9 设置压缩级别(1最快压缩,9最高压缩)
--fast 等同于-1,最快压缩
--best 等同于-9,最佳压缩(默认)
-d, --decompress 解压文件(同bunzip2)
-z, --compress 压缩文件(默认行为)
-k, --keep 压缩/解压后保留原始文件
-f, --force 强制覆盖已存在的输出文件
-t, --test 测试压缩文件的完整性
-c, --stdout 将结果输出到标准输出
-q, --quiet 静默模式,不显示警告信息
-v, --verbose 详细模式,显示处理信息
-s, --small 减少内存使用(适用于小内存系统)
-L, --license 显示软件许可证信息
-V, --version 显示版本信息
--help 显示帮助信息

压缩级别详解

级别 块大小 压缩速度 压缩率 内存使用 推荐场景
-1 (--fast) 100KB 最快 最低 最少 快速测试,临时文件
-2 200KB 较低 较少 日常压缩
-3 300KB 较快 中等 中等 一般用途
-4 400KB 中等 较好 中等 平衡模式
-5 500KB 较慢 较高 文档存档
-6 600KB 很好 长期存储
-7 700KB 很慢 非常好 很高 重要数据
-8 800KB 极慢 极好 极高 关键数据
-9 (--best) 900KB 最慢 最佳 最多 终极压缩

使用示例

1. 基本压缩操作 常用
示例
# 压缩单个文件(默认删除原文件)
bzip2 file.txt
# 生成:file.txt.bz2,原文件被删除

# 压缩多个文件
bzip2 file1.txt file2.txt file3.txt

# 压缩并保留原文件
bzip2 -k document.pdf
# 生成:document.pdf.bz2,原文件保留

# 压缩整个目录(配合tar)
tar -cjf archive.tar.bz2 directory/

# 压缩到标准输出
bzip2 -c file.txt > compressed.bz2
2. 使用不同压缩级别
# 快速压缩(低压缩率)
bzip2 -1 largefile.log
# 或
bzip2 --fast data.csv

# 默认压缩(-9,最高压缩率)
bzip2 important_document.txt
# 等同于
bzip2 -9 confidential.pdf

# 平衡压缩(推荐日常使用)
bzip2 -4 regular_file.txt

# 测试不同级别的效果
for i in {1..9}; do
    echo "级别 $i:"
    time bzip2 -k -$i testfile.txt
    ls -lh testfile.txt.bz2
    rm testfile.txt.bz2
    echo "---"
done
3. 解压操作
# 解压单个文件
bzip2 -d file.txt.bz2
# 或
bunzip2 file.txt.bz2

# 解压并保留原压缩文件
bzip2 -dk archive.bz2

# 解压到标准输出
bzip2 -dc file.txt.bz2

# 解压多个文件
bzip2 -d file1.bz2 file2.bz2 file3.bz2

# 解压tar.bz2文件
tar -xjf archive.tar.bz2
4. 测试文件完整性
# 测试单个压缩文件
bzip2 -t archive.bz2
# 无输出表示文件完整

# 测试多个文件
bzip2 -t file1.bz2 file2.bz2 file3.bz2

# 详细测试模式
bzip2 -tv data.bz2
# 输出:data.bz2: ok

# 在脚本中测试
if bzip2 -t backup.bz2 2>/dev/null; then
    echo "压缩文件完整"
else
    echo "警告:压缩文件可能损坏"
fi
5. 查看压缩文件信息
# 查看压缩文件信息
bzip2 -lv file.bz2
# 输出示例:
# file.bz2: 1.234:1, 8.100 bits/byte, 19.05% saved, 1024000 in, 830000 out.

# 查看文件但不解压
bzcat file.bz2 | head -20
bzcat file.bz2 | wc -l

# 搜索压缩文件内容
bzcat logfile.bz2 | grep "error"
bzcat access.log.bz2 | grep "404"

# 比较压缩文件内容
diff <(bzcat file1.bz2) <(bzcat file2.bz2)
6. 批量处理文件
# 压缩当前目录下所有.txt文件
for file in *.txt; do
    bzip2 -k "$file"
done

# 解压当前目录下所有.bz2文件
for file in *.bz2; do
    bzip2 -dk "$file"
done

# 批量压缩并移动到备份目录
mkdir -p backup
for file in *.log; do
    bzip2 -c "$file" > "backup/${file}.bz2"
done

# 使用find批量压缩
find . -name "*.log" -exec bzip2 -k {} \;

# 使用xargs批量解压
find . -name "*.bz2" -print0 | xargs -0 bzip2 -d
7. 实际工作场景
# 场景1:日志文件压缩
# 压缩旧日志文件
find /var/log -name "*.log" -mtime +30 -exec bzip2 -9 {} \;

# 场景2:数据库备份压缩
mysqldump -u root -p database_name | bzip2 -9 > backup.sql.bz2

# 场景3:网站备份
tar -cjf website_backup_$(date +%Y%m%d).tar.bz2 /var/www/html

# 场景4:源码分发
cd project-1.0
tar -cjf ../project-1.0.tar.bz2 .

# 场景5:传输前压缩
bzip2 -9c large_file.iso | ssh user@server "cat > /backup/compressed.bz2"

压缩算法原理

Burrows-Wheeler压缩算法流程
输入数据
Burrows-Wheeler变换(BWT)
移动到前端编码(MTF)
游程编码(RLE)
霍夫曼编码
输出.bz2文件
算法各阶段说明
# 1. Burrows-Wheeler变换(BWT)
# 将重复字符聚集在一起,便于后续压缩
原始数据: "banana"
BWT变换: "annb$aa"

# 2. 移动到前端编码(MTF)
# 用出现位置编码字符
BWT数据: "annb$aa"
MTF编码: "011001" (示例)

# 3. 游程编码(RLE)
# 压缩重复序列
MTF数据: "00001111"
RLE编码: "4,0,4,1"

# 4. 霍夫曼编码
# 用变长编码压缩数据
RLE数据: "4,0,4,1"
霍夫曼编码: 二进制流

与其他压缩工具对比

工具 格式 压缩率 速度 内存 特点 推荐用途
bzip2 .bz2 中等 较高 文本压缩优秀,开源 软件分发,文档
gzip .gz 中等 速度快,通用性好 日志,网络传输
xz .xz 很高 最高压缩率,LZMA2 归档,分发
zip .zip 中等 跨平台,广泛支持 Windows兼容
7z .7z 很高 中等 较高 高压缩率,多种算法 备份,存档
zstd .zst 可调 很快 中等 速度极快,可调压缩 实时压缩,打包
压缩性能测试示例
#!/bin/bash
# 压缩工具性能测试脚本

TEST_FILE="test_data.bin"
TEST_SIZE="100M"

echo "创建测试文件 ($TEST_SIZE)..."
dd if=/dev/urandom of="$TEST_FILE" bs=1M count=100 2>/dev/null

echo -e "\n=== 压缩性能测试 ==="
echo "工具      耗时(s)  压缩后大小  压缩率  内存峰值"

# gzip测试
echo -n "gzip      "
/usr/bin/time -f "%e" gzip -k -9 "$TEST_FILE" 2>&1 | tail -1 | tr '\n' ' '
ls -lh "${TEST_FILE}.gz" | awk '{printf "%8s  ", $5}'
echo -n "$(echo "scale=2; $(stat -c%s "${TEST_FILE}.gz")*100/$(stat -c%s "$TEST_FILE")" | bc)%  "
/usr/bin/time -v gzip -9 "$TEST_FILE" 2>&1 | grep "Maximum resident" | awk '{print $6}'
rm -f "${TEST_FILE}.gz"

# bzip2测试
echo -n "bzip2    "
/usr/bin/time -f "%e" bzip2 -k -9 "$TEST_FILE" 2>&1 | tail -1 | tr '\n' ' '
ls -lh "${TEST_FILE}.bz2" | awk '{printf "%8s  ", $5}'
echo -n "$(echo "scale=2; $(stat -c%s "${TEST_FILE}.bz2")*100/$(stat -c%s "$TEST_FILE")" | bc)%  "
/usr/bin/time -v bzip2 -9 "$TEST_FILE" 2>&1 | grep "Maximum resident" | awk '{print $6}'
bunzip2 "${TEST_FILE}.bz2" 2>/dev/null

# xz测试
echo -n "xz       "
/usr/bin/time -f "%e" xz -k -9 "$TEST_FILE" 2>&1 | tail -1 | tr '\n' ' '
ls -lh "${TEST_FILE}.xz" | awk '{printf "%8s  ", $5}'
echo -n "$(echo "scale=2; $(stat -c%s "${TEST_FILE}.xz")*100/$(stat -c%s "$TEST_FILE")" | bc)%  "
/usr/bin/time -v xz -9 "$TEST_FILE" 2>&1 | grep "Maximum resident" | awk '{print $6}'
unxz "${TEST_FILE}.xz" 2>/dev/null

# 清理
rm -f "$TEST_FILE"
echo -e "\n测试完成"

实际应用脚本

脚本1:自动备份压缩脚本
#!/bin/bash
# 自动备份和压缩脚本

# 配置
BACKUP_DIR="/backups"
SOURCE_DIRS=("/var/www" "/etc" "/home")
RETENTION_DAYS=30
COMPRESSION_LEVEL=9
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="backup_${DATE}"

# 创建备份目录
mkdir -p "$BACKUP_DIR"

echo "=== 开始备份 $(date) ==="

# 创建临时目录
TEMP_DIR=$(mktemp -d)
echo "临时目录: $TEMP_DIR"

# 备份各个目录
for dir in "${SOURCE_DIRS[@]}"; do
    if [ -d "$dir" ]; then
        dir_name=$(basename "$dir")
        echo "备份: $dir"

        # 使用tar创建归档
        tar -cf "$TEMP_DIR/${dir_name}.tar" -C "$(dirname "$dir")" "$(basename "$dir")" 2>/dev/null

        if [ $? -eq 0 ]; then
            echo "✓ 成功: $dir_name.tar"
        else
            echo "✗ 失败: $dir"
        fi
    else
        echo "警告: 目录不存在 - $dir"
    fi
done

# 压缩备份
echo -e "\n压缩备份文件..."
tar -cjf "$BACKUP_DIR/${BACKUP_NAME}.tar.bz2" -C "$TEMP_DIR" . --use-compress-prog="bzip2 -$COMPRESSION_LEVEL"

if [ $? -eq 0 ]; then
    # 计算压缩率
    original_size=$(du -sb "$TEMP_DIR" | cut -f1)
    compressed_size=$(stat -c%s "$BACKUP_DIR/${BACKUP_NAME}.tar.bz2")
    ratio=$(echo "scale=2; ($original_size - $compressed_size) * 100 / $original_size" | bc)

    echo "✓ 备份压缩完成"
    echo "原始大小: $(numfmt --to=iec $original_size)"
    echo "压缩大小: $(numfmt --to=iec $compressed_size)"
    echo "压缩率: ${ratio}%"

    # 创建MD5校验文件
    md5sum "$BACKUP_DIR/${BACKUP_NAME}.tar.bz2" > "$BACKUP_DIR/${BACKUP_NAME}.md5"
    echo "校验文件: ${BACKUP_NAME}.md5"
else
    echo "✗ 压缩失败"
fi

# 清理临时文件
rm -rf "$TEMP_DIR"
echo "临时文件已清理"

# 删除旧备份
echo -e "\n清理超过${RETENTION_DAYS}天的旧备份..."
find "$BACKUP_DIR" -name "backup_*.tar.bz2" -mtime +$RETENTION_DAYS -delete
find "$BACKUP_DIR" -name "backup_*.md5" -mtime +$RETENTION_DAYS -delete

echo -e "\n=== 备份完成 $(date) ==="
echo "备份文件: $BACKUP_DIR/${BACKUP_NAME}.tar.bz2"
脚本2:日志文件管理工具
#!/bin/bash
# 日志文件压缩和管理工具

LOG_DIR="/var/log"
COMPRESS_AFTER_DAYS=7
DELETE_AFTER_DAYS=90
COMPRESSION_LEVEL=6
MIN_SIZE="10M"

echo "=== 日志文件管理工具 ==="
echo "压缩超过${COMPRESS_AFTER_DAYS}天的日志"
echo "删除超过${DELETE_AFTER_DAYS}天的压缩日志"
echo "最小处理大小: $MIN_SIZE"
echo ""

# 查找需要压缩的日志文件
echo "查找符合条件的日志文件..."
find "$LOG_DIR" -type f -name "*.log" -mtime +$COMPRESS_AFTER_DAYS -size +$MIN_SIZE | while read logfile; do
    echo "处理: $(basename "$logfile")"

    # 检查文件是否正在被使用
    if lsof "$logfile" >/dev/null 2>&1; then
        echo "  ⚠ 文件正在使用,跳过"
        continue
    fi

    # 压缩日志文件
    echo -n "  压缩中..."
    if bzip2 -$COMPRESSION_LEVEL -k "$logfile"; then
        compressed_size=$(stat -c%s "${logfile}.bz2")
        original_size=$(stat -c%s "$logfile")
        ratio=$(echo "scale=1; ($original_size - $compressed_size) * 100 / $original_size" | bc)

        echo "✓ 完成 (压缩率: ${ratio}%)"

        # 清空原日志文件
        > "$logfile"
        echo "  原文件已清空"
    else
        echo "✗ 压缩失败"
    fi
done

echo -e "\n清理旧压缩文件..."
# 删除旧的压缩日志
find "$LOG_DIR" -type f -name "*.log.bz2" -mtime +$DELETE_AFTER_DAYS | while read compressed_log; do
    echo "删除: $(basename "$compressed_log")"
    rm -f "$compressed_log"
done

echo -e "\n磁盘使用统计:"
echo "日志目录: $LOG_DIR"
du -sh "$LOG_DIR"
echo -e "\n.bz2文件统计:"
find "$LOG_DIR" -name "*.bz2" -exec du -ch {} + | tail -1

echo -e "\n=== 处理完成 ==="
脚本3:智能压缩选择器
#!/bin/bash
# 智能压缩工具,根据文件类型选择最佳压缩方式

compress_file() {
    local file="$1"
    local method="$2"

    case $method in
        "bzip2")
            echo "使用bzip2压缩..."
            bzip2 -k -9 "$file"
            ;;
        "gzip")
            echo "使用gzip压缩..."
            gzip -k -9 "$file"
            ;;
        "xz")
            echo "使用xz压缩..."
            xz -k -9 "$file"
            ;;
        "none")
            echo "跳过压缩(小文件)"
            cp "$file" "${file}.copy"
            ;;
    esac
}

analyze_file() {
    local file="$1"

    # 检查文件类型
    file_type=$(file -b "$file")
    file_size=$(stat -c%s "$file")

    echo "文件: $(basename "$file")"
    echo "大小: $(numfmt --to=iec $file_size)"
    echo "类型: $file_type"

    # 根据文件类型和大小推荐压缩方法
    if [[ $file_size -lt 10240 ]]; then
        # 小于10KB的文件不压缩
        echo "推荐: 不压缩(文件太小)"
        echo "压缩方法: none"
        compress_file "$file" "none"
    elif [[ "$file_type" == *"ASCII text"* ]] || [[ "$file_type" == *"UTF-8"* ]]; then
        # 文本文件,bzip2通常表现最好
        echo "推荐: bzip2(文本文件)"
        echo "压缩方法: bzip2"
        compress_file "$file" "bzip2"
    elif [[ "$file_type" == *"executable"* ]] || [[ "$file_type" == *"ELF"* ]]; then
        # 可执行文件,xz通常更好
        echo "推荐: xz(可执行文件)"
        echo "压缩方法: xz"
        compress_file "$file" "xz"
    elif [[ "$file_type" == *"JPEG"* ]] || [[ "$file_type" == *"PNG"* ]] || [[ "$file_type" == *"GIF"* ]]; then
        # 图片文件,已经是压缩格式
        echo "推荐: gzip(图片文件)"
        echo "压缩方法: gzip"
        compress_file "$file" "gzip"
    elif [[ $file_size -gt 104857600 ]]; then
        # 大于100MB的文件,考虑速度
        echo "推荐: gzip(大文件,速度快)"
        echo "压缩方法: gzip"
        compress_file "$file" "gzip"
    else
        # 默认使用bzip2
        echo "推荐: bzip2(默认)"
        echo "压缩方法: bzip2"
        compress_file "$file" "bzip2"
    fi

    echo ""
}

# 主程序
if [ $# -eq 0 ]; then
    echo "用法: $0 文件1 [文件2 ...]"
    echo "示例: $0 *.txt"
    exit 1
fi

echo "=== 智能压缩工具 ==="
echo ""

for file in "$@"; do
    if [ -f "$file" ]; then
        analyze_file "$file"
    else
        echo "警告: 文件不存在 - $file"
    fi
done

echo "=== 压缩完成 ==="
echo ""
echo "结果对比:"
ls -lh *.bz2 *.gz *.xz *.copy 2>/dev/null | head -20

注意事项

重要注意事项:
  • 文件删除:默认压缩/解压后会删除原文件,使用-k选项保留
  • 内存需求:高压缩级别需要大量内存(900KB块需要约9MB内存)
  • 不可恢复:压缩是破坏性的,确保有原始文件备份
  • 二进制文件:对已压缩的二进制文件(如.jpg、.mp4)压缩效果有限
  • 文件权限:压缩不保存文件权限,解压后需要重新设置
  • 大文件处理:处理超大文件时注意磁盘空间和内存限制
  • 版本兼容:不同版本的bzip2压缩文件可能不完全兼容

常见问题

A: 它们是同一个程序的不同名称(硬链接或符号链接):
  • bzip2:默认压缩文件
  • bunzip2:默认解压文件(相当于bzip2 -d
  • bzcat:解压到标准输出(相当于bzip2 -dc
验证方法:
# 查看文件链接
ls -l $(which bzip2) $(which bunzip2) $(which bzcat)

# 检查是否同一个inode
ls -i $(which bzip2) $(which bunzip2) $(which bzcat)

# 测试功能相同
echo "test" > test.txt
bzip2 test.txt
bzcat test.txt.bz2
# 输出:test
bunzip2 test.txt.bz2
cat test.txt
# 输出:test

A: 根据需求选择压缩级别:
  • 快速压缩:使用-1--fast,适合临时文件、测试
  • 日常使用:使用-4-6,平衡速度和压缩率
  • 最高压缩:使用-9--best,适合备份、存档
  • 网络传输:考虑使用-2-3,减少压缩时间
  • 内存限制:小内存系统使用-1-3
建议:
# 开发环境,快速压缩
bzip2 -1 debug.log

# 生产环境,平衡压缩
bzip2 -4 production.log

# 长期存档,最高压缩
bzip2 -9 archive_data.txt

# 自动选择脚本
if [ $(stat -c%s "file.txt") -gt 1048576 ]; then
    # 大于1MB的文件使用中等压缩
    bzip2 -4 file.txt
else
    # 小文件使用快速压缩
    bzip2 -1 file.txt
fi

A: 各有优势,根据需求选择:
bzip2 gzip
压缩率 更高(文本) 中等
速度 较慢 更快
内存 较多 较少
兼容性 一般 极好
推荐场景 存档、分发、文本 日志、网络、实时
实际选择建议:
# 文本文件压缩 -> bzip2
bzip2 documentation.txt

# 日志文件压缩 -> gzip(更快)
gzip access.log

# 网络传输 -> gzip
cat file.txt | gzip | nc host 8080

# 备份存档 -> bzip2
tar -cjf backup.tar.bz2 /important/data

# 实时压缩 -> gzip
tail -f app.log | gzip > compressed.log.gz

相关命令

bunzip2

解压.bz2文件:

bunzip2 file.bz2
bunzip2 -k archive.bz2
bunzip2 *.bz2
bzcat

查看.bz2文件内容:

bzcat file.bz2
bzcat log.bz2 | grep error
bzcat data.bz2 | head -20
bzip2recover

恢复损坏的.bz2文件:

bzip2recover damaged.bz2
# 生成rec*.bz2文件
bunzip2 rec*.bz2
压缩比较

其他压缩工具:

gzip file.txt       # .gz格式
xz file.txt         # .xz格式
zstd file.txt       # .zst格式
7z a archive.7z file.txt