Bash脚本技术求助:实现带日期与版本号的文件自动重命名
Bash 文件自动版本控制脚本实现方案
核心问题分析
- 你遇到的核心问题是:单独生成的新文件名逻辑正确,但结合
cp使用时版本递增失效,本质是生成新文件名后没有循环检查文件是否存在并持续递增版本,仅生成一次就直接使用。 - 需要覆盖三类文件名场景:带日期+版本、仅带日期、仅带版本。
完整脚本实现
#!/bin/bash # 接收命令行传入的原始文件名,替换为固定值可直接测试 original_file="$1" if [ -z "$original_file" ]; then echo "请传入原始文件名作为参数" exit 1 fi # 分离文件名与后缀 filename="${original_file%.*}" extension="${original_file##*.}" if [ "$filename" = "$extension" ]; then extension="" else extension=".$extension" fi # 初始化解析变量 core_name="" version_num=1 # 用case语句解析不同格式的文件名 case "$filename" in *[0-9]{4}-[0-9]{2}-[0-9]{2}*V.[0-9]*) # 场景1:含日期和版本号 version_num=$(echo "$filename" | grep -oE 'V\.[0-9]+' | cut -d '.' -f 2) core_name=$(echo "$filename" | sed -E "s/[0-9]{4}-[0-9]{2}-[0-9]{2}//; s/V\.[0-9]+//; s/^[[:space:]]+//; s/[[:space:]]+$//") ;; *[0-9]{4}-[0-9]{2}-[0-9]{2}*) # 场景2:仅含日期,无版本号 core_name=$(echo "$filename" | sed -E "s/[0-9]{4}-[0-9]{2}-[0-9]{2}//; s/^[[:space:]]+//; s/[[:space:]]+$//") ;; *V.[0-9]*) # 场景3:仅含版本号,无日期 version_num=$(echo "$filename" | grep -oE 'V\.[0-9]+' | cut -d '.' -f 2) core_name=$(echo "$filename" | sed -E "s/V\.[0-9]+//; s/^[[:space:]]+//; s/[[:space:]]+$//") ;; *) # 场景4:无日期无版本号 core_name="$filename" ;; esac # 强制更新为当前日期 new_date=$(date +%Y-%m-%d) # 生成初始新文件名 new_filename="${new_date} ${core_name} V.${version_num}${extension}" # 循环检查文件是否存在,存在则递增版本号 while [ -f "$new_filename" ]; do version_num=$((version_num + 1)) new_filename="${new_date} ${core_name} V.${version_num}${extension}" done # 执行复制操作 cp "$original_file" "$new_filename" echo "已生成新版本文件:$new_filename"
关键逻辑说明
- 文件名解析:通过
case匹配不同格式的文件名,结合grep和sed提取核心名称、版本号,确保覆盖所有目标场景。 - 版本递增循环:生成初始文件名后,用
while循环持续检查文件是否存在,存在则自动递增版本号,直到找到未被占用的文件名——这直接解决了你之前cp时版本递增失效的问题。 - 后缀处理:单独分离文件后缀,避免
.pdf、.docx这类扩展名被误解析进核心名称。 - 日期强制更新:无论原始文件名是否包含日期,新文件名都会使用当前系统日期。
使用方式
直接在命令行传入原始文件名即可运行:
./version_control.sh "2024-02-12 Work Presentation V.1"
内容的提问来源于stack exchange,提问作者ReaderGuy42
相关产品推荐
相关产品推荐

