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

如何在Bash脚本的if条件中检测文件名含数字并实现数字递增

解决Bash脚本中文件名数字递增的问题

需求说明

原本尝试匹配Buchung_cdate_[0-9].pdf格式的文件,但实际需要实现:当目标文件已存在时,自动检测同基础名的带数字文件名,将数字加1生成新文件名(类似复制文件时a.pdf生成a_1.pdf、a_3.pdf的递增命名逻辑),之前用[0-9]的简单匹配无法满足动态递增的需求。

原脚本

#!/bin/bash

dir="/home/benji/Nextcloud/Buchhaltung/test/"
tag="Buchung"
images="(*.png|*.jpg|*.jpeg|*.JPG|*.JPEG|*.webp)"
#convert="convert $f "Buchung_cdate.pdf""

#Preperations
shopt -s extglob

#Actual script starting here – do not change unless you know what you are doing ;)
for f in $dir*$images; do #loop on every file that has extension $images
    if [[ "$f" != *$tag* ]]; then #exclude files of the loop with filename including $tag
      cdate="$(date -r "$f" +"%Y-%m-%d")" # 修正原脚本中多余的%符号
      if [[ -f $dir"Buchung_$cdate.pdf" ]]; then #checks if "Buchung_$cdate.pdf" matches an already existing file in $dir
        if [ -f $dir"Buchung_$cdate"_[0-9].pdf ]; then
          echo $f" - Already existing!"
        else
          echo $f" - Already existing! Convert!"
        fi
      #echo $f" - Already existing!"
      else
      echo $f" - cdate not equal --> convert to \"Buchung_cdate.pdf\"!"
    fi
    else
      echo $f" - I include \"Buchung\" in my filename - Do nothing"
    fi
done

解决思路与代码修改

核心逻辑是:先确定基础文件名,遍历已存在的同基础名带数字文件,找到最大数字后加1生成新文件名。替换原脚本中文件存在判断的部分:

#!/bin/bash

dir="/home/benji/Nextcloud/Buchhaltung/test/"
tag="Buchung"
images="(*.png|*.jpg|*.jpeg|*.JPG|*.JPEG|*.webp)"

#Preperations
shopt -s extglob

for f in "$dir"*$images; do
    if [[ "$f" != *"$tag"* ]]; then
        cdate="$(date -r "$f" +"%Y-%m-%d")"
        base="${dir}Buchung_${cdate}"
        target="${base}.pdf"

        if [[ -f "$target" ]]; then
            # 初始化最大数字为0
            max_num=0
            # 遍历所有带数字的同基础名PDF文件
            for existing in "${base}"_*.pdf; do
                # 跳过不存在的文件(当没有匹配项时,existing会是原字符串)
                [[ -f "$existing" ]] || continue
                # 用正则提取文件名中的数字部分
                num=$(echo "$existing" | sed -E "s/^${base}_([0-9]+)\.pdf$/\1/")
                # 更新最大数字
                if (( num > max_num )); then
                    max_num=$num
                fi
            done
            # 生成新的递增文件名
            new_num=$((max_num + 1))
            new_target="${base}_${new_num}.pdf"
            echo "$f - 基础文件已存在,将转换为 ${new_target}!"
            # 取消注释执行转换
            # convert "$f" "$new_target"
        else
            echo "$f - 将转换为 ${target}!"
            # convert "$f" "$target"
        fi
    else
        echo "$f - 文件名包含\"Buchung\",不处理"
    fi
done

关键细节说明

  • 正则提取数字:用sed -E的捕获组([0-9]+)精准提取文件名中的数字部分,确保只匹配纯数字后缀。
  • 数值比较:用(( num > max_num ))进行整数比较,避免字符串比较导致的逻辑错误(比如"10"和"2"的字符串比较会认为"2"更大)。
  • 变量安全:所有文件路径变量都用双引号包裹,避免文件名含空格或特殊字符时出现解析错误。
  • 边界处理:当没有带数字的同基础名文件时,max_num保持0,新数字从1开始,符合常规的递增逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 00:42:44