2011-01-09 21 views
5
kullanıyorum

bir for döngüsü 16 karaktere bir klasördeki tüm dosya adlarını kesecek şekilde buna benzer:bash: Eşsiz tutarak, dosya adları kesecek

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

sorundur: iki dosya ismi yaşadığımızda Aynı ilk 16 karakterden sonra, bir öncekinin üzerine yazılacaktır (OS X mv'de bu şekilde davranır).

"Shortname" adında bir dosyanın var olup olmadığını nasıl kontrol edebilirim, eğer varsa, "Shortname" öğesinin son karakterini bir sayı ile değiştirin. Ardından, bu ada sahip bir dosya varsa tekrar kontrol edin ve eğer öyleyse, daha yüksek bir sayı deneyin. Ve bunun gibi. Eğer 9 numaraya ulaşırsa ve şu ana kadar tüm isimler alınmışsa, "Shortname" in son TWO karakterini "10" ile değiştirmeli ve o dosyanın zaten mevcut olup olmadığını kontrol etmelidir.

Örnek: İçinde aşağıdaki dosyaları ile bir dizin var diyelim: ilk 16 harf tüm dosyalar için aynı olduğu

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

Not. Komut dosyasını çalıştırdıktan sonra, ben onlara bu şekilde yeniden adlandırılacak istiyorum:

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

"MyTerriblyLongLongFourteenthFile.jpg" alfabetik sıralamaya bağlıdır "MyTerriblyLong14.jpg" şeklinde adlandırılır, eğer önemli değildir. Her birinin benzersiz bir isim alması önemlidir.

Bunu yapmanın en iyi yolu nedir?

cevap

4

Önce bunu test dosyalarında deneyin. mv yerine echo kullanarak normal yöntem testi, potansiyel ad çarpışmalarının oluşturulmayacağı için size pek bir şey söylemeyecektir.

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

Test:

$ 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

Sen erkeksin. Çok teşekkürler! – Martin