写在前面
- 疫情期间整理
Synology
里存储了10多年的相片,这些相片穿越了功能手机到智能手机的年代。 - 不少照片非常有年代感,文件名同样也有年代感。五花八门……
- 最初用 exiv2 来读取照片的源信息,发现有些老照片没有源信息、新格式的照片读不到源信息。
- 然后用 exiftool 来识别了新照片的源信息和部分视频的源信息。
- 最后甚至还启用了 SQLite 数据库存储文件的源信息。
化繁为简
- 今日扫描了一遍文件系统,结合
SQLite
里的数据分析,发现仍有大量 照片/视频 的拍摄时间无法确定:
- 部分手机拍摄的全景照片
- 部分第三方拍照软件
- 从第三方软件另存的照片
- 部分视频文件
- 很久很久以前的照片
- 这些都是最美好的记忆,我要保存好它。所以我决定写个脚本去识别那个“乌七八糟”不规则的文件名,哪怕会有些不需要的照片也被整理进来。
- 总比把珍贵的照片现在就丢失了的好,未来还可以用图片识别去分类、去重,最终无法用程序处理的再人肉处理。想想都完美~
- 好,开始动手敲:
#!/bin/bash
# Rename.sh : Foramt the file name by rules
readonly iLog="./Rename.log" # 扫描日志
readonly eLog="./Rename.err"
readonly debug=false
readonly stdName="(^|[[:space:]])[2,1][0,9][0,1,2,7,9][0-9][0-1][0-9][0-3][0-9]-[0-2][0-9][0-5][0-9][0-5][0-9]($|[[:space:]])" # 标准格式
readonly er1Name="[0,3-9][0-9]{16,}" # 超长数字,提前过滤避免被错误解析
readonly er2Name="[0-9]{18,}" # 异长数字,提前过滤避免被错误解析
readonly er3Name="(^|[[:space:]])-[0-9]{6,}" # 长负数,提前过滤避免被错误解析
readonly minTime=$(date -d '2000-01-11 22:33:44' +%s) # 不存在比这个时间更早的文件
readonly nt1Name="[2,1][0,9][0,1,7,9][0-9][0-1][0-9][0-3][0-9]_[0-2][0-9][0-5][0-9][0-5][0-9]" # 包含 20090516_105959
readonly nt2Name="[2,1][0,9][0,1,7,9][0-9][0-1][0-9][0-3][0-9][0-2][0-9][0-5][0-9][0-5][0-9]" # 包含 20180916112233
readonly nt3Name="[2,1][0,9][0,1,7,9][0-9]_[0-1][0-9]_[0-3][0-9]_[0-2][0-9]_[0-5][0-9]_[0-5][0-9]" # 包含 2018_09_16_11_22_33
readonly nt4Name="[2,1][0,9][0,1,7,9][0-9]-[0-1][0-9]-[0-3][0-9] [0-2][0-9][0-5][0-9][0-5][0-9]" # 包含 2009-05-16 223344
readonly nt5Name="[2,1][0,9][0,1,7,9][0-9]-[0-1][0-9]-[0-3][0-9]-[0-2][0-9]-[0-5][0-9]-[0-5][0-9]" # 包含 2018-09-16-11-22-33
readonly secName="[1,9][0-9]{8,9}" # 包含秒级时间戳,支持2000年之后
find /volume1/homes/{higkoo,anglix}/Drive/{Backup,Moments} ! -path "*@eaDir*" -type f | while read -r sPath; do
unset fName fExt nName rCode rMove tStr
fExt="${sPath##*.}"
[[ ${fExt,,} =~ "png" ]] && continue # 丢弃截图
[[ ${sExt,,} == "jpeg" ]] && sExt='jpg' # 将jpeg后缀改为jpg
fName="${sPath##*/}" && fName="${fName%%.*}"
if [[ $fName =~ $stdName ]]; then # case 的正则弱于 [[ ]] ,所以这里使用 if 嵌套
rCode=0 && rMove=false && echo -ne '.'
elif [[ $fName =~ $er1Name || $fName =~ $er2Name || $fName =~ $er3Name ]]; then
rCode='A' && rMove=false && echo -ne '#'
echo "$sPath" >> ${eLog}
elif [[ $fName =~ $nt1Name ]]; then
rCode=1 && rMove=true && echo -ne "$rCode"
nName="${BASH_REMATCH[0]/_/-}"
elif [[ $fName =~ $nt2Name ]]; then
rCode=2 && rMove=true && echo -ne "$rCode"
nName="${BASH_REMATCH[0]:0:8}-${BASH_REMATCH[0]:8:6}"
elif [[ $fName =~ $nt3Name ]]; then
rCode=3 && rMove=true && echo -ne "$rCode"
nName="${BASH_REMATCH[0]//_/}" && nName="${nName:0:8}-${nName:8:6}"
elif [[ $fName =~ $nt4Name ]]; then
rCode=4 && rMove=true && echo -ne "$rCode"
nName="${BASH_REMATCH[0]//-/}" && nName="${nName/ /-}"
elif [[ $fName =~ $nt5Name ]]; then
rCode=5 && rMove=true && echo -ne "$rCode"
nName="${BASH_REMATCH[0]//-/}" && nName="${nName:0:8}-${nName:8:6}"
elif [[ $fName =~ $secName ]]; then
tStr="${BASH_REMATCH[0]}"
if [[ $tStr -le $minTime || $tStr -ge $(date +%s) ]]; then
rCode='B' && rMove=false && echo -ne '-'
echo "$sPath" >> ${eLog}
else
rCode=8 && echo -ne "$rCode"
nName="$(date -d @$tStr +%Y%m%d-%H%M%S)"
fi
else
rCode='E' && echo -ne '*'
echo "$sPath" >> ${eLog}
continue
fi
$rMove && mv -v "${sPath}" "${sPath%/*}/${nName}.${fExt,,}" >>${iLog} 2>>${eLog}
$debug && declare -p rCode BASH_REMATCH && exit 0
done
- 脚本很快就跑完了,成功找回近
7657
张相片/视频。 - 还剩下两千多张,看了下文件名确实无法判断。后期人肉处理,先开心一会~
来源:oschina
链接:https://my.oschina.net/higkoo/blog/3189397