批量压缩并打包的脚本

wen 实用脚本 1

本文目录导读:

批量压缩并打包的脚本

  1. 基础版本
  2. 高级版本(带更多功能)
  3. 简易批量打包脚本
  4. 使用示例
  5. 保存和使用
  6. 高级用法(添加定时任务)

我来为您提供一个批量压缩并打包的Shell脚本,支持多种场景:

基础版本

#!/bin/bash
# 批量压缩打包脚本
# 用法: ./batch_compress.sh [源目录] [输出目录]
# 设置颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 默认配置
SOURCE_DIR="${1:-./files}"          # 需要压缩的目录
OUTPUT_DIR="${2:-./archives}"       # 压缩包输出目录
COMPRESS_TYPE="tar.gz"              # 压缩类型
MAX_SIZE="100M"                     # 单个压缩包最大大小
# 创建输出目录
mkdir -p "$OUTPUT_DIR"
# 日志函数
log() {
    echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1"
}
error() {
    echo -e "${RED}[错误]${NC} $1"
}
warn() {
    echo -e "${YELLOW}[警告]${NC} $1"
}
# 检查源目录
if [ ! -d "$SOURCE_DIR" ]; then
    error "源目录 $SOURCE_DIR 不存在"
    exit 1
fi
# 主函数
main() {
    log "开始批量压缩..."
    log "源目录: $SOURCE_DIR"
    log "输出目录: $OUTPUT_DIR"
    local count=0
    # 方式1:压缩目录中的所有子目录
    for dir in "$SOURCE_DIR"/*/; do
        [ -d "$dir" ] || continue
        # 获取目录名
        dirname=$(basename "$dir")
        timestamp=$(date '+%Y%m%d_%H%M%S')
        archive_name="${dirname}_${timestamp}.${COMPRESS_TYPE}"
        archive_path="$OUTPUT_DIR/$archive_name"
        log "正在压缩: $dirname"
        # 根据压缩类型执行
        case "$COMPRESS_TYPE" in
            tar.gz)
                tar -czf "$archive_path" -C "$SOURCE_DIR" "$dirname"
                ;;
            tar.bz2)
                tar -cjf "$archive_path" -C "$SOURCE_DIR" "$dirname"
                ;;
            zip)
                (cd "$SOURCE_DIR" && zip -r "$archive_path" "$dirname")
                ;;
        esac
        if [ $? -eq 0 ]; then
            log "✓ 完成: $archive_name ($(du -sh "$archive_path" | cut -f1))"
            count=$((count+1))
        else
            error "✗ 压缩失败: $dirname"
        fi
    done
    log "批量压缩完成,共处理 $count 个目录"
}
# 执行
main

高级版本(带更多功能)

#!/bin/bash
# 高级批量压缩打包脚本
# 功能:按大小分卷、排除指定文件、多类型支持
set -e  # 出错即停止
# 配置
SOURCE_DIR="${1:-./data}"
OUTPUT_DIR="${2:-./backups}"
COMPRESS_TYPE="${3:-tar.gz}"        # tar.gz / tar.bz2 / zip / tar.xz
MAX_FILE_SIZE="50M"                 # 单文件最大大小
SPLIT_SIZE=""                       # 分卷大小,如 "100M" 留空不分卷
EXCLUDE_PATTERNS=("*.tmp" "*.log" "node_modules" ".git")
PARALLEL=1                          # 并行压缩数量
# 颜色
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# 创建输出目录
mkdir -p "$OUTPUT_DIR"
# 日志函数
log() {
    echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1"
}
error() {
    echo -e "${RED}[错误]${NC} $1"
}
warn() {
    echo -e "${YELLOW}[警告]${NC} $1"
}
info() {
    echo -e "${BLUE}[信息]${NC} $1"
}
# 显示帮助
show_help() {
    cat << EOF
用法: $0 [源目录] [输出目录] [压缩类型]
参数:
    源目录      需要压缩的目录,默认: ./data
    输出目录    压缩包保存位置,默认: ./backups
    压缩类型    tar.gz / tar.bz2 / zip / tar.xz,默认: tar.gz
示例:
    $0 /var/www ./backup tar.gz
    $0 ./logs ./archive zip
    $0 /data ./backup tar.bz2
EOF
    exit 0
}
# 检查参数
if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
    show_help
fi
# 检查依赖
check_dependencies() {
    local deps=("tar")
    case "$COMPRESS_TYPE" in
        *.gz) deps+=("gzip") ;;
        *.bz2) deps+=("bzip2") ;;
        *.xz) deps+=("xz") ;;
        *.zip) deps+=("zip") ;;
    esac
    for dep in "${deps[@]}"; do
        if ! command -v "$dep" &> /dev/null; then
            error "缺少依赖: $dep"
            exit 1
        fi
    done
}
# 处理单个目录
compress_directory() {
    local dir="$1"
    local output_base="$2"
    local dirname=$(basename "$dir")
    local timestamp=$(date '+%Y%m%d_%H%M%S')
    local archive_name="${dirname}_${timestamp}"
    local archive_path="$output_base/${archive_name}"
    # 检查目录大小
    local dir_size=$(du -sh "$dir" | cut -f1)
    # 构建排除参数
    local exclude_args=()
    for pattern in "${EXCLUDE_PATTERNS[@]}"; do
        exclude_args+=("--exclude=$pattern")
    done
    # 根据压缩类型处理
    case "$COMPRESS_TYPE" in
        tar.gz)
            local final_path="${archive_path}.tar.gz"
            man tar -czf "$final_path" "${exclude_args[@]}" -C "$SOURCE_DIR" "$dirname"
            ;;
        tar.bz2)
            local final_path="${archive_path}.tar.bz2"
            tar -cjf "$final_path" "${exclude_args[@]}" -C "$SOURCE_DIR" "$dirname"
            ;;
        tar.xz)
            local final_path="${archive_path}.tar.xz"
            tar -cJf "$final_path" "${exclude_args[@]}" -C "$SOURCE_DIR" "$dirname"
            ;;
        zip)
            local final_path="${archive_path}.zip"
            (cd "$SOURCE_DIR" && zip -r "$final_path" "$dirname" \
                ${EXCLUDE_PATTERNS[@]/#/-x } 2>/dev/null || \
             zip -r "$final_path" "$dirname")
            ;;
    esac
    # 如果需要分卷
    if [ -n "$SPLIT_SIZE" ] && [ -f "$final_path" ]; then
        local actual_size=$(du -sh "$final_path" | cut -f1)
        if [ "$actual_size" ] && [[ "${actual_size//[!0-9]/}" -gt "${SPLIT_SIZE//[!0-9]/}" ]]; then
            split -b "$SPLIT_SIZE" "$final_path" "${final_path%.*}_part_"
            rm "$final_path"
            info "已分卷: ${final_path%.*}_part_*"
        fi
    fi
    # 输出结果
    if [ -f "$final_path" ]; then
        local size=$(du -sh "$final_path" | cut -f1)
        echo -e "${GREEN}✓${NC} $dirname ($dir_size) -> $size"
        return 0
    else
        echo -e "${RED}✗${NC} $dirname 压缩失败"
        return 1
    fi
}
# 主函数
main() {
    # 检查源目录
    if [ ! -d "$SOURCE_DIR" ]; then
        error "源目录 $SOURCE_DIR 不存在"
        exit 1
    fi
    check_dependencies
    log "开始批量压缩"
    info "源目录: $SOURCE_DIR"
    info "输出目录: $OUTPUT_DIR"
    info "压缩类型: $COMPRESS_TYPE"
    # 统计目录数量
    local total=0
    local success=0
    local failed=0
    # 查找所有子目录
    local dirs=()
    while IFS= read -r -d '' dir; do
        dirs+=("$dir")
    done < <(find "$SOURCE_DIR" -mindepth 1 -maxdepth 1 -type d -print0)
    total=${#dirs[@]}
    info "共发现 $total 个目录需要压缩"
    # 处理目录
    local jobs=()
    for dir in "${dirs[@]}"; do
        # 并行处理
        if [ "$PARALLEL" -gt 1 ]; then
            compress_directory "$dir" "$OUTPUT_DIR" &
            jobs+=("$!")
            # 控制并行数量
            if [ "${#jobs[@]}" -ge "$PARALLEL" ]; then
                for job in "${jobs[@]}"; do
                    wait "$job"
                done
                jobs=()
            fi
        else
            if compress_directory "$dir" "$OUTPUT_DIR"; then
                ((success++))
            else
                ((failed++))
            fi
        fi
    done
    # 等待剩余任务
    for job in "${jobs[@]}"; do
        wait "$job" && ((success++)) || ((failed++))
    done
    info "压缩完成!"
    echo -e "${GREEN}成功: $success${NC} / ${RED}失败: $failed${NC} / 总计: $total"
}
# 执行主函数
main "$@"

简易批量打包脚本

#!/bin/bash
# 简易批量打包 - 适用于快速打包多个目录
# 将当前目录下的所有子目录分别打包
SOURCE_DIR="${1:-.}"
OUTPUT_DIR="${2:-./packages}"
TYPE="${3:-tar.gz}"  # tar.gz 或 zip
mkdir -p "$OUTPUT_DIR"
echo "=========================================="
echo "开始批量打包"
echo "源目录: $SOURCE_DIR"
echo "输出目录: $OUTPUT_DIR"
echo "=========================================="
# 遍历所有子目录
for dir in "$SOURCE_DIR"/*/; do
    if [ -d "$dir" ]; then
        name=$(basename "$dir")
        echo "打包: $name"
        case "$TYPE" in
            tar.gz)
                tar -czf "$OUTPUT_DIR/${name}.tar.gz" -C "$SOURCE_DIR" "$name"
                ;;
            zip)
                (cd "$SOURCE_DIR" && zip -r "$OUTPUT_DIR/${name}.zip" "$name")
                ;;
            *)
                echo "不支持的格式: $TYPE"
                exit 1
                ;;
        esac
    fi
done
echo "=========================================="
echo "批量打包完成!"
echo "文件保存在: $OUTPUT_DIR"
echo "=========================================="

使用示例

# 1. 基本用法
./batch_compress.sh /path/to/files ./output
# 2. 指定压缩格式
./batch_compress.sh ./data ./backup zip
# 3. 查看帮助
./batch_compress.sh -h
# 4. 打包当前目录下的所有子文件夹
./batch_compress.sh . ./archives tar.gz
# 5. 高级用法 - 排除特定文件
./batch_compress.sh /var/www ./backup tar.bz2

保存和使用

# 保存脚本
vim batch_compress.sh
# 添加执行权限
chmod +x batch_compress.sh
# 运行脚本
./batch_compress.sh

高级用法(添加定时任务)

# 添加到 crontab 定时执行
crontab -e
# 每天凌晨2点执行
0 2 * * * /path/to/batch_compress.sh /var/www /backup/weekly tar.gz
# 也可以写成备份轮换脚本
#!/bin/bash
# 保留最近7天的备份
BACKUP_DIR="./backups"
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +7 -delete
/path/to/batch_compress.sh /data "$BACKUP_DIR" tar.gz

这个脚本支持:

  • ✅ 批量压缩多个目录
  • ✅ 支持 tar.gz、tar.bz2、zip 等格式
  • ✅ 自动排除指定文件
  • ✅ 可设置最大文件大小
  • ✅ 支持分卷压缩
  • ✅ 并行处理(提高效率)
  • ✅ 详细日志输出
  • ✅ 错误处理

根据您的具体需求选择合适的版本即可!

抱歉,评论功能暂时关闭!