You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写Shell脚本批量按规则压缩日期命名的文件夹?

嘿,这个需求我之前碰到过类似的,给你写个实用的Shell脚本,顺便拆解下逻辑,保证你能看懂也能复用~

核心思路

咱们要解决的问题分两步:

  1. 按月份分组:因为要求每个月内的文件夹单独处理,不能跨月打包;
  2. 每3个一组打包:每个月里的文件夹按日期排序后,每凑够3个就打包,剩下不足3个的也单独打包,文件名要包含组内第一个和最后一个文件夹的日期(和你给的示例格式一致)。
完整脚本

直接把下面的代码保存成pack_daily_folders.sh就行:

#!/bin/bash

# 获取当前目录下所有符合YYYYMMDD格式的文件夹,按日期排序
folders=$(ls -d [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/ 2>/dev/null | sort)

# 如果没有找到符合条件的文件夹,直接退出
if [ -z "$folders" ]; then
    echo "⚠️ 没有找到符合YYYYMMDD格式的日期文件夹"
    exit 1
fi

# 按月份分组,每3个文件夹打包一次
echo "$folders" | awk '
BEGIN {
    current_month = ""
    group = []
    group_count = 0
}
{
    # 去掉文件夹名末尾的斜杠,提取月份(前6位:YYYYMM)
    folder = $0
    sub(/\/$/, "", folder)
    month = substr(folder, 1, 6)
    
    # 切换月份时,先处理上一个月份剩余的文件
    if (month != current_month) {
        if (current_month != "" && group_count > 0) {
            pack_group(group, group_count)
        }
        current_month = month
        delete group
        group_count = 0
    }
    
    # 将当前文件夹加入组
    group[++group_count] = folder
    
    # 每凑够3个就打包
    if (group_count == 3) {
        pack_group(group, group_count)
        delete group
        group_count = 0
    }
}
END {
    # 处理最后一个月份剩余的不足3个的文件
    if (group_count > 0) {
        pack_group(group, group_count)
    }
}

# 打包函数:生成文件名并执行tar命令
function pack_group(arr, cnt,    first, last, tar_name, cmd) {
    first = arr[1]
    last = arr[cnt]
    # 生成和示例一致的文件名:同月的话后面的日期只保留后两位
    if (substr(first, 1, 6) == substr(last, 1, 6)) {
        tar_name = "mytar-" first "_" substr(last, 7) ".tar.bz2"
    } else {
        tar_name = "mytar-" first "_" last ".tar.bz2"
    }
    # 构建tar命令
    cmd = "tar jcvf " tar_name " "
    for (i=1; i<=cnt; i++) {
        cmd = cmd arr[i] " "
    }
    print "✅ 执行打包命令:" cmd
    system(cmd)
}
'
脚本关键部分解释
  1. 文件夹筛选与排序:

    • ls -d [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/:精准匹配8位数字命名的文件夹;
    • sort:因为YYYYMMDD格式的字符串直接排序就是日期顺序,完美解决日期不连续的问题。
  2. 按月份分组逻辑:

    • 用current_month变量跟踪当前处理的月份(前6位字符),一旦月份变化,就先把上一个月剩余的文件夹打包,再切换到新月份。
  3. 打包文件名生成:

    • 如果组内所有文件夹都在同一个月,文件名就用mytar-YYYYMMDD_XXDD.tar.bz2的格式(比如你示例里的mytar-20171002_1005.tar.bz2);
    • 极端情况如果跨月(不过脚本已经按月份分组,这种情况不会出现),会生成完整的日期拼接文件名。
使用注意事项
  • 给脚本加执行权限:chmod +x pack_daily_folders.sh;
  • 测试阶段可以先把system(cmd)这一行注释掉,只看打印出来的命令,确认没问题再执行实际打包;
  • 如果你的文件夹不在当前目录,可以修改ls命令的路径,比如ls -d /path/to/your/folders/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/。

内容的提问来源于stack exchange,提问作者user9624737

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:32:49