Yedekleme dosyalarını dosya adına son ek olarak kullanarak ve artık gizlenmeyecek şekilde nasıl yeniden adlandırılır

Aug 17 2020

Ç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

1 Minty Aug 17 2020 at 09:57

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