बैकअप फ़ाइल का नाम कैसे बदलें, इसके बैकअप संस्करण को फ़ाइल नाम में प्रत्यय के रूप में उपयोग करते हुए इसे अब छिपाया नहीं गया है

Aug 17 2020

मैं बड़ी संख्या में छवि फ़ाइलों के साथ काम कर रहा हूं। इसका एक हिस्सा सभी छवि फ़ाइल प्रकारों को स्थानांतरित कर रहा था जो 1000+ निर्देशिकाओं में सीधे एक एकल में फैले हुए थे। कई तस्वीरें ऐसी थीं जिनका सही नाम समान था, लेकिन वास्तव में अलग तस्वीरें थीं। मैंने ऐसा करने के लिए निम्नलिखित एक-लाइनर का उपयोग किया:

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