如何在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
相关产品推荐
相关产品推荐

