Bash脚本开发:文件名版本号递增、日期修正及防覆盖需求
Bash脚本:文件名日期修正与版本号递增优化
需求说明
- 检查文件名前10位的日期是否为当日,若不是则替换为当日日期
- 无论日期是否修正,都必须将文件名末尾的版本号递增
- 绝对不能覆盖已有文件,若目标文件名已存在,则自动生成下一个可用的版本号(比如已有
V.33,就生成V.34)
现有脚本问题
之前的脚本运行后会生成重复编号的文件名(例如2023-09-12 Name V.3233.md),同时无法避免覆盖已存在的文件。
修复后的脚本
#!/bin/bash # 检查是否传入文件名参数 if [[ $# -ne 1 ]]; then echo "用法: $0 <文件名>" exit 1 fi original_file="$1" today=$(date +"%Y-%m-%d") # 验证原文件是否存在 if [[ ! -f "$original_file" ]]; then echo "错误: 文件 '$original_file' 不存在" exit 1 fi # 拆分文件名和扩展名 file_base="${original_file%.*}" file_ext="${original_file##*.}" # 使用正则表达式提取版本号和版本前缀(比如匹配 "V.32" 中的 "V." 和 "32") if [[ "$file_base" =~ ^(.*[[:space:]]V\.)([0-9]+)$ ]]; then version_prefix="${BASH_REMATCH[1]}" current_version="${BASH_REMATCH[2]}" else # 如果没有找到版本号,默认从V.1开始 echo "警告: 未找到有效版本号,将从V.1开始" # 提取日期之后的名称部分(如果原文件名有日期前缀) if [[ "$file_base" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}[[:space:]](.*)$ ]]; then name_part="${BASH_REMATCH[1]}" else name_part="$file_base" fi version_prefix="${name_part} V." current_version=0 fi # 处理日期部分:提取原文件名前10位的日期,替换为当日日期 if [[ "$file_base" =~ ^([0-9]{4}-[0-9]{2}-[0-9]{2})([[:space:]].*)$ ]]; then new_name_prefix="${today}${BASH_REMATCH[2]}" # 替换掉原有的版本前缀和版本号,保留名称部分 new_name_base="${new_name_prefix%${version_prefix}${current_version}}" else # 如果原文件名没有日期前缀,直接添加当日日期 new_name_base="${today} ${file_base%${version_prefix}${current_version}}" fi # 循环查找下一个可用的版本号,避免覆盖文件 next_version=$((current_version + 1)) while true; do new_file="${new_name_base}${version_prefix}${next_version}.${file_ext}" if [[ ! -f "$new_file" ]]; then break fi next_version=$((next_version + 1)) done # 复制文件到新文件名 cp "$original_file" "$new_file" echo "已生成新文件: $new_file"
关键修复点
- 准确提取版本号:改用正则表达式匹配版本号格式(比如
V.32),避免原脚本中提取非数字字符后所有数字导致的重复编号问题。 - 循环检查文件存在性:通过循环递增版本号,直到找到一个不存在的文件名,彻底解决文件覆盖问题。
- 日期修正逻辑优化:准确拆分原文件名的日期部分和名称部分,替换为当日日期后,正确拼接版本号,避免拼接错误。
- 参数与文件校验:增加了参数检查和原文件存在性验证,提升脚本的健壮性。
内容的提问来源于stack exchange,提问作者ReaderGuy42
相关产品推荐
相关产品推荐

