2011-01-09 12 views
5

Ich verwende ein for-Schleife ähnlich wie diese alle Dateinamen in einem Ordner zu 16 Zeichen zu kürzen:bash: Kürzen Dateinamen, sie einzigartig zu halten

for i in *; do 
    Shortname=${i:0:16}  # Let's assume I don't need the extension 
    mv "$i" "$Shortname" 
done 

Das Problem ist: Wenn zwei Dateinamen haben die gleiche erste 16 Zeichen, das spätere überschreibt das vorherige (auf OS X verhält sich mv so).

Wie kann ich überprüfen, ob eine Datei mit dem Namen "Kurzname" bereits existiert, und wenn ja, ersetzen Sie das letzte Zeichen von "Kurzname" durch eine Zahl. Überprüfen Sie dann erneut, ob eine Datei mit diesem Namen vorhanden ist, und versuchen Sie es gegebenenfalls mit einer höheren Nummer. Und so weiter. Wenn es bei Nummer 9 ankommt und bis jetzt alle Namen genommen wurden, sollte es die letzten zwei Zeichen des "Kurznamens" durch "10" ersetzen und prüfen, ob diese Datei bereits existiert.

Beispiel: Lassen Sie uns sagen, dass ich ein Verzeichnis mit den folgenden Dateien darin haben:

MyTerriblyLongLongFirstFile.jpg 
MyTerriblyLongLongSecondFile.jpg 
MyTerriblyLongLongThirdFile.jpg 
... 
MyTerriblyLongLongFourteenthFile.jpg 
... 
MyTerriblyLongLongOneHundredSixtySeventhFile.jpg 
... 
MyTerriblyLongLongFiveMillionthFile.jpg 

Beachten Sie, dass die ersten 16 Buchstaben die gleichen für alle Dateien. Nachdem das Skript ausgeführt wird, würde Ich mag sie dazu umbenannt werden:

MyTerriblyLongL1.jpg 
MyTerriblyLongL2.jpg 
MyTerriblyLongL3.jpg 
... 
MyTerriblyLong14.jpg 
... 
MyTerriblyLon167.jpg 
... 
MyTerribl5000000.jpg 

Es spielt keine Rolle, ob „MyTerriblyLongLongFourteenthFile.jpg“ auf „MyTerriblyLong14.jpg“ umbenannt wird, die auf alphabetische Sortierung abhängt. Es ist nur wichtig, dass jeder einen eindeutigen Namen erhält.

Was ist der beste Weg, dies zu tun?

Antwort

4

Probieren Sie zuerst die Testdateien aus. Die übliche Testmethode mit echo anstelle von mv wird Ihnen nicht viel sagen, da die möglichen Namenskollisionen nicht erstellt werden.

#!/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 
+0

Du bist der Mann. Danke vielmals! – Martin