यदि आप एक ही समय में फ़ाइलों और निर्देशिकाओं का नाम बदलना चाहते हैं, तो आप कुछ समस्याओं में भाग लेंगे । सिर्फ एक फ़ाइल का नाम बदलना काफी आसान है। लेकिन आप यह सुनिश्चित करना चाहते हैं कि निर्देशिकाओं का भी नाम बदला जाए। आप बस नहीं कर सकते हैं 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)।