本文目录导读:

我来为您提供一个批量压缩并打包的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 等格式
- ✅ 自动排除指定文件
- ✅ 可设置最大文件大小
- ✅ 支持分卷压缩
- ✅ 并行处理(提高效率)
- ✅ 详细日志输出
- ✅ 错误处理
根据您的具体需求选择合适的版本即可!