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

如何在Bash中筛选各服务器组下最新的.vbk格式全量备份文件

筛选每个服务器组的最新.vbk备份文件

针对你的需求,这里提供两种可靠的实现方法,分别基于文件名中的时间戳和系统文件修改时间来筛选最新文件,同时给出脚本的完整优化建议:

方法一:基于文件名中的时间戳筛选

你的文件名格式包含可排序的时间戳Dyyyy-mm-ddThhmmss,可以直接提取该部分进行比较,确保准确对应备份生成时间,不受系统文件时间变动影响。

实现代码

#!/bin/bash

# 初始化关联数组,存储每个服务器组的最新文件
declare -A latest_files

# 遍历所有.vbk文件
for file in *.vbk; do
    # 跳过非文件(比如目录或空匹配)
    [[ ! -f "$file" ]] && continue

    # 提取服务器标识(从开头到"D"之前的部分,即"服务器名 - IP")
    server_id=$(echo "$file" | sed -n 's/\(.*D\).*/\1/p' | sed 's/D$//')
    # 提取时间戳部分(D后面到_之前的部分)
    timestamp=$(echo "$file" | sed -n 's/.*D\([0-9-T]*\)_.*/\1/p')

    # 对比当前服务器组已记录的最新时间戳,更新为更大的那个
    if [[ -z "${latest_files[$server_id]}" ]]; then
        latest_files[$server_id]="$file"
    else
        # 提取已记录文件的时间戳
        existing_timestamp=$(echo "${latest_files[$server_id]}" | sed -n 's/.*D\([0-9-T]*\)_.*/\1/p')
        # 比较时间戳(因为格式是yyyy-mm-ddThhmmss,字符串比较即可)
        if [[ "$timestamp" > "$existing_timestamp" ]]; then
            latest_files[$server_id]="$file"
        fi
    fi
done

# 输出每个服务器组的最新文件
echo "筛选出的最新全量备份文件:"
for server in "${!latest_files[@]}"; do
    echo "- $server: ${latest_files[$server]}"
done

代码说明

  • 用关联数组latest_files来分组存储每个服务器的最新文件,键是服务器的“名称-IP”标识
  • 通过sed命令精准提取服务器标识和时间戳,避免文件名中其他字符干扰
  • 利用时间戳的字符串排序特性(yyyy-mm-ddThhmmss格式天然支持字典序比较),直接判断哪个时间更新

方法二:基于系统文件修改时间筛选

如果备份文件的系统修改时间和实际生成时间一致,这种方法更简洁,依赖系统文件属性来排序。

实现代码

#!/bin/bash

# 按修改时间倒序列出所有.vbk文件,然后按服务器分组取第一个
ls -lt -- *.vbk 2>/dev/null | awk '
    BEGIN { prev_server = "" }
    {
        # 提取服务器标识(从开头到"D"之前的部分)
        match($NF, /(.*D)/, server_match)
        server_id = substr(server_match[1], 1, length(server_match[1])-1)
        # 只保留每个服务器组的第一个(最新的)文件
        if (server_id != prev_server) {
            print $NF
            prev_server = server_id
        }
    }
'

代码说明

  • ls -lt按修改时间从新到旧列出文件
  • awk遍历列表,提取每个文件的服务器标识,只输出每个组的第一个(最新的)文件
  • 2>/dev/null用来屏蔽当目录中没有.vbk文件时的错误提示

额外实用建议(针对你的完整需求)

  1. 定时任务设置:要实现每月第一个周一执行,在crontab中添加以下规则(编辑crontab用crontab -e):

    # 每月第一个周一的凌晨2点执行脚本
    0 2 * * 1 [ "$(date +\%d)" -le 7 ] && /path/to/your/backup_script.sh
    
  2. 复制到归档服务器:筛选出文件后,用rsync或scp复制,推荐rsync(支持断点续传、增量同步):

    # 遍历筛选出的文件,复制到归档服务器
    for file in "${latest_files[@]}"; do
        rsync -avz "$file" user@归档服务器IP:/path/to/archive/dir/
    done
    
  3. 错误处理与日志:新手脚本建议添加日志记录和错误判断,比如:

    # 定义日志文件路径
    LOG_FILE="/var/log/backup_sync.log"
    # 输出到日志
    echo "$(date '+%Y-%m-%d %H:%M:%S') 开始同步备份文件" >> "$LOG_FILE"
    # 复制时判断是否成功
    if rsync -avz "$file" user@归档服务器IP:/path/to/archive/dir/; then
        echo "$(date '+%Y-%m-%d %H:%M:%S') 成功复制文件: $file" >> "$LOG_FILE"
    else
        echo "$(date '+%Y-%m-%d %H:%M:%S') 复制失败: $file" >> "$LOG_FILE"
        exit 1
    fi
    
  4. 大小写兼容:如果服务器名存在大小写差异(比如示例中的Webserver和WebServer),可以将服务器标识转为小写统一分组,修改server_id的提取逻辑:

    server_id=$(echo "$file" | sed -n 's/\(.*D\).*/\1/p' | sed 's/D$//' | tr '[:upper:]' '[:lower:]')
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 22:20:39