![Bash 脚本递归重命名文件而不更改文件扩展名](https://linux22.com/image/209444/Bash%20%E8%84%9A%E6%9C%AC%E9%80%92%E5%BD%92%E9%87%8D%E5%91%BD%E5%90%8D%E6%96%87%E4%BB%B6%E8%80%8C%E4%B8%8D%E6%9B%B4%E6%94%B9%E6%96%87%E4%BB%B6%E6%89%A9%E5%B1%95%E5%90%8D.png)
我试图将父目录和所有子目录中的所有文件(.jpg、.jpeg、.mov 等)重命名为 date_time_7digitnumber 而不更改文件扩展名。下面的脚本完成了此任务,但它运行了多次,改变了已经正确的内容。这是完整的脚本。任何帮助将不胜感激!
系统:MacOS Monterey v12.5 Homebrew 安装了 coreutils 以供 gdate 使用
#!/usr/bin/env bash
clear
RED='\033[0;31m'
NC='\033[0m'
shopt -s globstar nocaseglob nocasematch nullglob
echo
echo
echo -e "${RED}********** Your current directory path is " $PWD " **********${NC}"
read -p "
********** This function is going to rename all media files with **********
********** Date-Time-7digit number **********
********** !!THIS ACTION CAN NOT BE UNDONE!! **********
********** !!MAKE SURE TO CHANGE TO THE CORRECT DIRECTORY!! **********
*** ARE YOU ABSOLUTELY SURE YOU ARE IN THE CORRECT DIRECTORY AND WISH TO PROCEED? ***
[Y]es or [N]o " -n 1 -r
echo # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]
then
n=1
for f in * ; do
find . -type f -print0 |
while IFS= read -r -d '' f ; do
dd=$(dirname "$f")
ext=${f##*.}
new=$(gdate -r "$f" +"%Y%m%d_%H%M%S")-$(printf "%07d%s" "$n")
mv -vn "$f" "$dd"/"$new"."$ext" ; ((n++))
done
done
Echo
Echo Renaming Process Complete!
Echo
afplay /System/Library/Sounds/Ping.aiff
afplay /System/Library/Sounds/Ping.aiff
afplay /System/Library/Sounds/Ping.aiff
fi
答案1
我将替换您的代码的以下部分,
n=1
for f in * ; do
find . -type f -print0 |
while IFS= read -r -d '' f ; do
dd=$(dirname "$f")
ext=${f##*.}
new=$(gdate -r "$f" +"%Y%m%d_%H%M%S")-$(printf "%07d%s" "$n")
mv -vn "$f" "$dd"/"$new"."$ext" ; ((n++))
done
done
通过这段代码:
DATE=$(date -r "$f" +"%Y%m%d_%H%M%S")
LOG="RENAME_${DATE}.log" ; rm -f "${LOG}"
ERR="RENAME_${DATE}.err" ; rm -f "${ERR}"
n=1
for f in *
do
dd=$(dirname "$f")
ext=${f##*.}
new=${DATE}-$(printf "%07d%s" "$n")
COM="mv -vn '${f}' '${dd}/${new}.${ext}'"
### LOG Everything for potential recovery action or later troubleshooting search
echo "${new}.${ext}|${f}|${PWD}|${COM}"
${COM} >&2 2>>"${ERR}"
((n++))
done >"${LOG}" 2>&1
目的如下:
- 这寻找操作没有任何意义(除非您期望去寻找子目录内容,但您似乎建议情况并非如此),
- 这尽管find 命令消失后没有任何作用,
- 减少计算每个文件的日期的工作(没有必要,除非您想使用统计数据根据文件的实际创建日期命名文件),以及
- 在信息之前记录以供以后可能的调查使用,以及
- 记录实际重命名操作报告的特定错误。
我想进一步评论说,使用简单的“是”响应(有时我们按错键)运行脚本所带来的风险将决定需要将目录的完整路径指定为命令行参数,从而强制需要有意识地指定脚本启动之前的预期“目标”,以及使其成为一个工具,然后可以从批处理中调用该工具来处理潜在的目录列表。