วิธีเปลี่ยนชื่อไฟล์สำรองโดยใช้เวอร์ชันสำรองเป็นส่วนต่อท้ายชื่อไฟล์และทำให้ไม่ถูกซ่อนอีกต่อไป

Aug 17 2020

ฉันทำงานกับไฟล์ภาพจำนวนมาก ส่วนหนึ่งของสิ่งนี้คือการย้ายไฟล์รูปภาพทุกประเภทที่แพร่กระจายไปทั่วกว่า 1,000 ไดเรกทอรีมาไว้ในไฟล์เดียวโดยตรง มีหลายภาพที่มีชื่อเหมือนกัน แต่เป็นภาพที่แตกต่างกัน ฉันใช้ซับเดียวต่อไปนี้ในการทำเช่นนั้น:

find . -type f -exec mv --backup=t '{}' /media/DATA-HDD/AllImages \;

ฉันทำวิธีนี้เพื่อให้ภาพใด ๆ ที่มีชื่อเดียวกันจะได้รับไฟล์สำรองที่ซ่อนไว้แทนที่จะเขียนทับ มันทำงานได้ดีมาก แต่ตอนนี้ฉันมีปัญหาอีกอย่างที่ฉันต้องแก้ไข

ตอนนี้ฉันมีกระเบื้องมากมายที่มีดังต่อไปนี้:

DSC_0616.NEF
DSC_0616.NEF.~1~
DSC_0616.NEF.~2~

สิ่งที่ฉันต้องการทำคือเรียกใช้คำสั่ง (หรือสคริปต์) ซึ่งจะเปลี่ยนชื่อไฟล์ที่ซ่อนอยู่เหล่านี้โดยการเพิ่มหมายเลขสำรองเป็นคำต่อท้ายชื่อไฟล์และลบ. ~ [bu #] ~ เพื่อทำให้ไม่ซ้ำกัน ชื่อไฟล์และไม่ถูกซ่อน ดังนั้น:

DSC_0616.NEF
DSC_0616_1.NEF
DSC_0616_2.NEF

ฉันใช้เวลาส่วนที่ดีกว่าในสองสามชั่วโมงในการพยายามค้นคว้าเพื่อพยายามทำสิ่งนี้ด้วยตัวเอง แต่ไม่พบสิ่งใดที่จะช่วยให้ฉันไปถึงจุดนั้นได้ซึ่งอยู่ในขอบเขตความรู้ของฉันในหัวข้อนี้

คำตอบ

1 Minty Aug 17 2020 at 09:57

ตราบเท่าที่คุณมั่นใจว่าทุกอย่างได้รับการตั้งชื่ออย่างสม่ำเสมอตามที่คุณอธิบายไว้ข้างต้นนิพจน์ทั่วไปบางอย่างสามารถทำให้งานสำเร็จผ่านเชลล์สคริปต์:

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

สิ่งนี้จะทำงานเพื่อลดหลั่นผ่านไดเร็กทอรีเช่นกันเพียงแค่วางสคริปต์และเรียกใช้งานด้วยไดเร็กทอรีการทำงานของคุณที่ด้านบนสุดของแผนผังไดเร็กทอรีของโปรเจ็กต์ ทำงานกับไฟล์ตัวอย่างเช่นที่คุณระบุ:

###@###:~/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~

หลังจากเรียกใช้สคริปต์:

###@###:~/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