Yedekleme dosyalarını dosya adına son ek olarak kullanarak ve artık gizlenmeyecek şekilde nasıl yeniden adlandırılır
Çok sayıda resim dosyasıyla çalışıyorum. Bunun bir kısmı, 1000'den fazla dizine yayılan tüm görüntü dosyası türlerini doğrudan tek bir dizine taşımaktı. Aynı adı taşıyan ama aslında farklı resimler olan birçok resim vardı. Bunu yapmak için aşağıdaki tek satırı kullandım:
find . -type f -exec mv --backup=t '{}' /media/DATA-HDD/AllImages \;
Bunu bu şekilde yaptım, böylece aynı ada sahip herhangi bir görüntünün üzerine yazmak yerine gizli bir yedekleme dosyası oluşturuldu. Çok iyi çalıştı, ama şimdi çözmem gereken başka bir sorun var.
Şimdi, elbette, aşağıdakilere benzer pek çok karo var:
DSC_0616.NEF
DSC_0616.NEF.~1~
DSC_0616.NEF.~2~
Yapmak istediğim şey, yedekleme numarasını dosya adına sonek olarak ekleyerek bu gizli dosyalardan herhangi birini yeniden adlandıracak bir komut (veya komut dosyası) çalıştırmak ve onları benzersiz kılmak için. ~ [Bu #] ~ öğesini kaldırmaktır. dosya adları ve gizli değil. Öyleyse, şöyle:
DSC_0616.NEF
DSC_0616_1.NEF
DSC_0616_2.NEF
Bunu kendim denemek için birkaç saatin daha iyi bir kısmını araştırmaya harcadım, ancak konuyla ilgili bilgi alanımda oraya ulaşmama yardımcı olacak hiçbir şey bulamıyorum.
Yanıtlar
Her şeyin yukarıda tanımladığınız gibi tutarlı bir şekilde adlandırıldığından emin olduğunuz sürece, bazı normal ifadeler işi bir kabuk betiği aracılığıyla halledebilir:
#!/bin/bash
# sets the file separator to be only newlines, in case files have spaces in them
IFS=$'\n' for file in $(find . -type f); do
# parses just the number(s) between two tildes, and only at the end of the file
number=$(echo $file | grep -Eo "~[0-9]+~$" | sed s/'~'/''/g) # if no match found, assume this is a "base" file that does not need to be renamed if [ "$number" == "" ]; then
continue
fi
# parses the file name through "NEF", then deletes ".NEF"
filename=$(echo $file | grep -Eio "^.+\.NEF" | sed s/'\.NEF'/''/g )
if [ "$filename" == "" ]; then continue fi mv -v $file $(echo "$filename"_"$number.NEF") # if anything went wrong, exit immediately if [ "$?" != "0" ]; then
echo "Unable to move file $file"
exit 1
fi
done
Bu, dizinler arasında aşağı inmek için de işe yarar, sadece komut dosyasını yerleştirin ve projenizin dizin ağacının en üstüne çalışma dizininizle birlikte çalıştırın. Sağladığınız gibi örnek dosyalarla çalışmak:
###@###:~/project$ find . -type f
./DSC_0616.NEF.~8~
./DSC_0616.NEF.~5~
./DSC_0616.NEF.~1~
./DSC_0616.NEF.~7~
./DSC_0616.NEF.~3~
./DSC_0616.NEF.~4~
./DSC_0616.NEF.~9~
./DSC_0616.NEF.~2~
./DSC_0616.NEF.~6~
./lower_dir/DSC_0616.NEF.~8~
./lower_dir/DSC_0616.NEF.~5~
./lower_dir/DSC_0616.NEF.~1~
./lower_dir/DSC_0616.NEF.~7~
./lower_dir/DSC_0616.NEF.~3~
./lower_dir/DSC_0616.NEF.~4~
./lower_dir/DSC_0616.NEF.~9~
./lower_dir/DSC_0616.NEF.~2~
./lower_dir/DSC_0616.NEF.~6~
betiği çalıştırdıktan sonra:
###@###:~/project$ find . -type f
./DSC_0616_1.NEF
./DSC_0616_3.NEF
./DSC_0616_7.NEF
./DSC_0616_5.NEF
./DSC_0616_2.NEF
./DSC_0616_9.NEF
./DSC_0616_6.NEF
./DSC_0616_8.NEF
./DSC_0616_4.NEF
./lower_dir/DSC_0616_1.NEF
./lower_dir/DSC_0616_3.NEF
./lower_dir/DSC_0616_7.NEF
./lower_dir/DSC_0616_5.NEF
./lower_dir/DSC_0616_2.NEF
./lower_dir/DSC_0616_9.NEF
./lower_dir/DSC_0616_6.NEF
./lower_dir/DSC_0616_8.NEF
./lower_dir/DSC_0616_4.NEF