批处理文件重命名:比随机 ID 更好的方法来防止删除具有重复文件名的文件?

批处理文件重命名:比随机 ID 更好的方法来防止删除具有重复文件名的文件?

我想重命名过去假期的一堆照片,这些照片是由不同的人使用不同的设备(手机、相机等)从不同的角度拍摄的。我刚刚写了一个 bash 脚本来帮助我:

#!/bin/bash
for f in *; do
  # generate random id to prevent deletion of files with duplicate names 
  randomid=$(tr -dc "[:alnum:]" < /dev/urandom | head -c 10)
  # add modification date and time including seconds to the filename, attach location and random id 
  mv -- "$f" "$(date +%Y-%m-%d-%R:%S -r "${f}")_location_${randomid}.jpg";
done

结果是名称如下所示的文件:2016-08-09-15:56:24_location_uPe38A20tn.jpg

我必须添加随机 ID,因为有一些图片是在同一日期和第二个时间拍摄的,因此文件最终会具有重复的文件名,并在此过程中被删除。

除了我使用随机 ID 的想法之外,您是否还看到另一种方法来确保在同一日期同一秒拍摄的照片不会被删除?

感谢您的帮助!

答案1

这将给出重复的数字 1、2、3 等。

dest=$(date +%Y-%m-%d-%R:%S -r "${f}")_location_
id=
while [ -f "$dest""$id".jpg ] ; do
    ((id++))
done
dest="$dest""$id".jpg
mv -- "$f" "$dest"

它应该放在for f in *循环内。

答案2

我在这里没有看到任何随机区分符的充分理由。如果您没有自然名称来区分文件,请使用计数器,它看起来更友好。简单的解决方案是使用系统的全局计数器。

counter=1
for f in *; do
  base="$(date +%Y-%m-%d-%R:%S -r "${f}")_location_"
  mv -- "$f" "$base_$counter.jpg"
  counter=$((counter+1))
done

如果您只想在发生冲突时使用计数器,请在重命名之前测试文件名。

for f in *; do
  base="$(date +%Y-%m-%d-%R:%S -r "${f}")_location_"
  set -- "$base"*.jpg
  if [ -e "$1" ]; then
    if [ "$1" = "$base.jpg" ]; then
      mv "$base.jpg" "$base_1.jpg"
    fi
    mv "$base.jpg" "$base_$(($#+1)).jpg"
  else
    mv -- "$f" "$base.jpg"
  fi
done

(警告,未经测试的代码)

答案3

以下是对您的脚本的一些小改进。它会提示可能的重复项并考虑文件扩展名:

#!/bin/bash

# for each file
for f in *.{jpg,jpeg}; do
  # generate random id to prevent deletion of duplicates
  randomid=$(tr -dc "[:alnum:]" < /dev/urandom | head -c 10)
  # add modification date and time (divided by dashes) to the current filename
  # -i prompts on possible duplicates. 
  mv -i -- "$f" "$(date +%Y-%m-%d-%R:%S -r "${f}")_location_${randomid}.jpg";
done

相关内容