我使用类似于此的 for 循环将文件夹中的所有文件名截断为 16 个字符:
for i in *; do
Shortname=${i:0:16} # Let's assume I don't need the extension
mv "$i" "$Shortname"
done
问题是:每当两个文件名具有相同的前 16 个字符时,后一个文件名将覆盖前一个文件名(在 OS X mv 上就是这样)。
如何检查名称为“Shortname”的文件是否已存在,如果存在,则将“Shortname”的最后一个字符替换为数字。然后再次检查是否存在具有该名称的文件,如果存在,请尝试更大的数字。等等。如果它到达数字 9 并且到目前为止所有名称都已被占用,则它应该用“10”替换“Shortname”的最后两个字符,并检查该文件是否已存在。
示例:假设我有一个目录,其中包含以下文件:
MyTerriblyLongLongFirstFile.jpg
MyTerriblyLongLongSecondFile.jpg
MyTerriblyLongLongThirdFile.jpg
...
MyTerriblyLongLongFourteenthFile.jpg
...
MyTerriblyLongLongOneHundredSixtySeventhFile.jpg
...
MyTerriblyLongLongFiveMillionthFile.jpg
请注意,所有文件的前 16 个字母都相同。运行脚本后,我希望将它们重命名为:
MyTerriblyLongL1.jpg
MyTerriblyLongL2.jpg
MyTerriblyLongL3.jpg
...
MyTerriblyLong14.jpg
...
MyTerriblyLon167.jpg
...
MyTerribl5000000.jpg
如果“MyTerriblyLongLongFourteenthFile.jpg”重命名为“MyTerriblyLong14.jpg”也没关系,这取决于字母排序。重要的是他们每个人都有一个独特的名字。
做这个的最好方式是什么?
首先在测试文件上尝试此操作。通常的测试方法是使用echo
代替mv
不会告诉您太多信息,因为不会创建潜在的名称冲突。
#!/bin/bash
num=1
length=16
for file in M*.jpg
do
newname=$file
until [[ ! -f $newname ]]
do
(( sublen = length - ${#num} ))
printf -v newname '%.*s%d' "$sublen" "$file" "$num"
(( num++ ))
done
mv "$file" "$newname"
done
Testing:
$ touch MyTerriblyLongLongFilenames{a..k}.jpg
$ touch MyTerriblyLongL3
$ ls M*
MyTerriblyLongL3 MyTerriblyLongLongFilenamesf.jpg
MyTerriblyLongLongFilenamesa.jpg MyTerriblyLongLongFilenamesg.jpg
MyTerriblyLongLongFilenamesb.jpg MyTerriblyLongLongFilenamesh.jpg
MyTerriblyLongLongFilenamesc.jpg MyTerriblyLongLongFilenamesi.jpg
MyTerriblyLongLongFilenamesd.jpg MyTerriblyLongLongFilenamesj.jpg
MyTerriblyLongLongFilenamese.jpg MyTerriblyLongLongFilenamesk.jpg
$ ./nocollide
$ ls M*
MyTerriblyLong10 MyTerriblyLongL1 MyTerriblyLongL4 MyTerriblyLongL7
MyTerriblyLong11 MyTerriblyLongL2 MyTerriblyLongL5 MyTerriblyLongL8
MyTerriblyLong12 MyTerriblyLongL3 MyTerriblyLongL6 MyTerriblyLongL9
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)