Ubuntu下如何按年月/文件类型/时间属性批量压缩文件优化空间
SFTP目录批量压缩落地方案
前置检查
- 先确认操作用户对SFTP存储目录有读写权限,权限不足的话命令前加
sudo执行即可,操作完成后记得把生成的压缩包权限对齐SFTP运行用户,避免影响正常文件访问 - 执行
df -h确认当前磁盘剩余空间不低于待压缩文件总大小的10%,防止压缩中途空间不足损坏文件 - 首次操作前建议先给目录打快照(云服务器用系统快照、本地盘用LVM快照均可),避免操作失误丢失数据
说明:原生gzip不支持多文件直接归档,方案采用tar归档+gzip压缩的组合方式,压缩包后缀按需求保留
.gzip命名,解压时用tar -zxf 包名.gzip即可正常读取。
可灵活配置维度的批量压缩脚本
脚本默认支持4种分组维度,可选择压缩后是否删除原文件,压缩包命名完全匹配需求示例,Ubuntu系统自带所有依赖工具,无需额外安装软件。
#!/bin/bash # 参数校验 if [ $# -lt 3 ]; then echo "用法: $0 <分组维度: year/year_month/ext/year_ext> <是否删原文件: true/false> <SFTP目录绝对路径>" echo "示例1: 按年压缩不删原文件: $0 year false /data/sftp/files" echo "示例2: 按年+文件类型压缩 校验后删原文件: $0 year_ext true /data/sftp/files" exit 1 fi GROUP_DIM=$1 DEL_SOURCE=$2 TARGET_DIR=$3 # 校验参数合法性 if [[ ! "$GROUP_DIM" =~ ^(year|year_month|ext|year_ext)$ ]]; then echo "分组维度仅支持: year/year_month/ext/year_ext" exit 1 fi if [[ ! "$DEL_SOURCE" =~ ^(true|false)$ ]]; then echo "删除原文件参数仅支持: true/false" exit 1 fi if [ ! -d "$TARGET_DIR" ]; then echo "目标目录不存在: $TARGET_DIR" exit 1 fi cd "$TARGET_DIR" || exit 1 # 遍历所有非gzip后缀的普通文件,按维度分组压缩 find . -maxdepth 1 -type f ! -name "*.gzip" -print0 | while IFS= read -r -d '' file; do filename=$(basename "$file") # 取文件修改时间(Linux全发行版通用,无兼容性问题) mtime=$(stat -c "%Y" "$file") file_year=$(date -d @"$mtime" +"%Y") file_month=$(date -d @"$mtime" +"%m") file_ext="${filename##*.}" # 生成对应分组的压缩包名 case $GROUP_DIM in "year") archive="document_${file_year}.gzip" ;; "year_month") archive="document_${file_year}${file_month}.gzip" ;; "ext") archive="document_all_${file_ext}.gzip" ;; "year_ext") archive="document_${file_year}_${file_ext}.gzip" ;; esac # 同组文件归集压缩 tar -rzf "$archive" "$filename" echo "已将 $filename 归入压缩包 $archive" # 校验文件已写入压缩包后再按配置删除原文件 if [ "$DEL_SOURCE" = "true" ]; then if tar -tf "$archive" | grep -qF "$filename"; then rm -f "$filename" echo "已校验完成,删除原文件 $filename" else echo "警告: $filename 写入压缩包失败,跳过删除" fi fi done echo "所有任务执行完成,压缩包存放在 $TARGET_DIR 目录下" echo "解压命令参考: tar -zxf 压缩包名.gzip"
使用方法
- 把上述代码保存为
sftp_compress.sh,执行chmod +x sftp_compress.sh赋予执行权限 - 常用场景命令参考:
- 首次测试执行(按年压缩,不删除原文件,用于验证效果):
./sftp_compress.sh year false 你的SFTP目录绝对路径 - 按年份+文件类型分组压缩,校验通过后删除原文件(最常用的归档场景,对应示例命名
document_2021_csv.gzip):./sftp_compress.sh year_ext true 你的SFTP目录绝对路径 - 按年月维度压缩(适合按月生成的报表、日志类文件):
./sftp_compress.sh year_month false 你的SFTP目录绝对路径 - 按文件类型全量压缩(比如单独压缩所有xlsx、所有csv文件):
./sftp_compress.sh ext false 你的SFTP目录绝对路径
- 首次测试执行(按年压缩,不删除原文件,用于验证效果):
适配调整说明
- 如果文件存放在多级子目录,需要递归压缩的话,把脚本里find命令的
-maxdepth 1参数删除即可 - 追求更高压缩率的话,可以把tar命令的
-z(gzip压缩)参数换成-J(xz压缩),压缩率比gzip高30%左右,只是压缩速度稍慢,后缀仍可保留.gzip,解压时把tar命令的z换成J即可 - 需要定期自动执行的话,把命令加到crontab定时任务即可,比如配置每月1号自动压缩上月文件,无需手动操作
- 首次执行务必把删除原文件参数设为
false,抽查几个压缩包确认文件完整无损坏后,再执行带删除参数的任务,避免数据丢失 - 如果是定期增量压缩,建议在find命令后加
-mtime +30这类时间筛选参数,只压缩超过指定天数未修改的文件,避免重复处理已经归档过的内容
内容的提问来源于stack exchange,提问作者user9548463
相关产品推荐
相关产品推荐

