यदि आप एक ही समय में फ़ाइलों और निर्देशिकाओं का नाम बदलना चाहते हैं, तो आप कुछ समस्याओं में भाग लेंगे । सिर्फ एक फ़ाइल का नाम बदलना काफी आसान है। लेकिन आप यह सुनिश्चित करना चाहते हैं कि निर्देशिकाओं का भी नाम बदला जाए। आप बस नहीं कर सकते हैं mv Motörhead/Encöding Motorhead/Encoding
के बाद से Motorhead
कॉल के समय मौजूद नहीं होंगे।
इसलिए, हमें सभी फ़ाइलों और फ़ोल्डरों की गहराई-पहले ट्रैवर्सल की आवश्यकता है, और फिर केवल वर्तमान फ़ाइल या फ़ोल्डर का नाम बदलें। निम्नलिखित find
मेरे OS X पर GNU और बैश 4.2.42 के साथ काम करता है।
#!/usr/bin/env bash
find "$1" -depth -print0 | while IFS= read -r -d '' file; do
d="$( dirname "$file" )"
f="$( basename "$file" )"
new="${f//[^a-zA-Z0-9\/\._\-]/}"
if [ "$f" != "$new" ] # if equal, name is already clean, so leave alone
then
if [ -e "$d/$new" ]
then
echo "Notice: \"$new\" and \"$f\" both exist in "$d":"
ls -ld "$d/$new" "$d/$f"
else
echo mv "$file" "$d/$new" # remove "echo" to actually rename things
fi
fi
done
new="${f//[\\\/\:\*\?\"<>|]/}"
यदि आप ऐसी किसी भी चीज़ को बदलना चाहते हैं, जिसे आप नहीं संभाल सकते हैं, तो आप रेगेक्स को बदल सकते हैं।
इस स्क्रिप्ट को इस रूप में सहेजें rename.sh
, इसे निष्पादन योग्य बनाएं chmod +x rename.sh
। फिर, इसे कॉल करें rename.sh /some/path
।
किसी भी फ़ाइल नाम टकराव (" Notice
" घोषणाओं) को हल करना सुनिश्चित करें ।
यदि आपको पूरा यकीन है कि यह सही प्रतिस्थापन करता है, echo
तो स्क्रिप्ट से हटा दें कि वास्तव में चीजों को फिर से नाम दें केवल मुद्रण के बजाय यह क्या करता है।
सुरक्षित होने के लिए, मैं इसे पहले फाइलों के एक छोटे उपसमुच्चय पर परीक्षण करने की सलाह दूंगा।
विकल्प समझाया
यह बताने के लिए कि यहाँ क्या होता है:
-depth
यह सुनिश्चित करेगा कि निर्देशिकाओं की गहराई-पहले पुनरावृत्ति की जाए, इसलिए हम अंत से सब कुछ "रोल अप" कर सकते हैं। आमतौर पर, find
अलग-अलग तरीके से पता चलता है (लेकिन चौड़ाई पहले नहीं)।
-print0
यह सुनिश्चित करता है कि find
आउटपुट शून्य-सीमांकित है, इसलिए हम इसे चर read -d ''
में पढ़ सकते हैं file
। ऐसा करने से हमें सभी प्रकार के अजीब फ़ाइल नामों से निपटने में मदद मिलती है, जिनमें रिक्त स्थान और यहां तक कि नए अंक भी शामिल हैं।
- हमें फ़ाइल की निर्देशिका मिल जाएगी
dirname
। हमेशा अपने चर को ठीक से उद्धृत करने के लिए मत भूलना, अन्यथा रिक्त स्थान या गोलाकार पात्रों के साथ कोई भी पथ इस स्क्रिप्ट को तोड़ देगा।
- हमें वास्तविक फ़ाइल नाम (या निर्देशिका नाम) मिलेगा
basename
।
- फिर, हम
$f
बैश की स्ट्रिंग प्रतिस्थापन क्षमताओं का उपयोग करने से किसी भी अमान्य चरित्र को हटाते हैं । अमान्य का मतलब है कि कुछ भी नहीं- या अपरकेस अक्षर, एक अंक, एक स्लैश ( \/
), एक डॉट ( \.
), एक अंडरस्कोर, या एक माइनस-हाइफ़न।
- यदि
$f
पहले से ही साफ है (साफ किया गया नाम वर्तमान नाम के समान है), तो इसे छोड़ दें।
- यदि
$new
पहले से ही निर्देशिका में मौजूद है $d
(उदाहरण के लिए, आपके पास नाम resume
और résumé
उसी निर्देशिका में फ़ाइलें हैं ), तो चेतावनी जारी करें। आप इसका नाम नहीं बदलना चाहते, क्योंकि, कुछ सिस्टम पर, mv foo foo
समस्या का कारण बनता है। अन्यथा,
- हम अंततः मूल फ़ाइल (या निर्देशिका) को उसके नए नाम में बदल देते हैं
इस के बाद से ही गहरी पदानुक्रम पर कार्य करेगा, का नाम बदलने Motörhead/Encöding
के लिए Motorhead/Encoding
दो चरणों में किया जाता है:
mv Motörhead/Encöding Motörhead/Encoding
mv Motörhead Motorhead
यह सुनिश्चित करता है कि सभी प्रतिस्थापन सही क्रम में किए गए हैं।
उदाहरण फ़ाइलें और परीक्षण रन
चलो एक बेस फ़ोल्डर में कुछ फ़ाइलों को कहते हैं test
:
test
test/Motörhead
test/Motörhead/anöther_file.mp3
test/Motörhead/Encöding
test/Randöm
test/Täst
test/Täst/Töst
test/with space
test/with-hyphen.txt
test/work
test/work/resume
test/work/résumé
test/work/schedule
यहाँ डिबग मोड में एक रन से आउटपुट है ( echo
सामने के साथ mv
), यानी, कमांड्स जिन्हें कहा जाएगा, और टकराव की चेतावनी:
mv test/Motörhead/anöther_file.mp3 test/Motörhead/another_file.mp3
mv test/Motörhead/Encöding test/Motörhead/Encoding
mv test/Motörhead test/Motorhead
mv test/Randöm test/Random
mv test/Täst/Töst test/Täst/Tost
mv test/Täst test/Tast
mv test/with space test/withspace
Notice: "resume" and "résumé" both exist in test/work:
-rw-r—r-- … … test/work/resume
-rw-r—r-- … … test/work/résumé
सूचना के लिए गए संदेशों के अभाव with-hyphen.txt
, schedule
है, और test
अपने आप में।
mv
पहले से मौजूद है, जो तब हो सकता है (1) यदि आपके पास पहले से साफ (परिणामस्वरूपmv foo foo
), या (2) फाइलें हैं, तो आपके पास एक ही नाम वाली फाइलें हैं विशेष वर्णों के लिए (उदाहरण के लिएmv Encöding Encoding
, जहां आपके पास पहले से ही एकEncoding
फ़ाइल हैEncöding
)।