मैं अपरकेस को पुन: उपयोग करने के लिए हर नाम का उपयोग कैसे कर सकता हूं


11

मैं बड़े पैमाने पर सभी फ़ाइलों और फ़ोल्डरों (उप-फ़ोल्डरों) को अपरकेस में बदलना चाहता हूं।

मुझे कुछ स्क्रिप्ट मिलीं, जो इसे कम करने के लिए करेंगी, लेकिन मुझे नहीं पता कि उन्हें कैसे बदलना है, इसलिए यह इसे दूसरे तरीके से (नीचे से ऊपर) कर देगा।

स्क्रिप्ट जो मुझे मिली और लोअरकेस के लिए काम करती है, लेकिन मुझे नहीं पता था कि कैसे संशोधित किया जाए:

rename 'y/A-Z/a-z/' *

से है man rename


नाम बदलें आदेश के बारे में कुछ भी जाने बिना, मुझे संदेह है कि यदि आप कोशिश करते rename 'y/a-z/A-Z/' *हैं तो आपको वही मिलेगा जो आप चाहते हैं। सावधान जहाँ आप इसके माध्यम से परीक्षण करते हैं।
वार्विक

यह पुनरावृत्ति नहीं है (क्योंकि प्रारंभिक एक नहीं था ...) लेकिन यह काम करता है। मुझे समझ नहीं आ रहा है कि मैं उस गलत पर क्यों नहीं लड़ी :), तत्कालीन!
जेंघी - अलेक्जेंड्रू जंटिया

मुझे लगता है कि गिल्स के जवाब की गुणवत्ता को देखते हुए, यह अच्छा होगा कि आप मेरे जवाब को वरीयता में स्वीकार करें। यह मेरी तुलना में बहुत अधिक पूर्ण है और आपके विकल्पों की व्याख्या करता है (और यह कैसे काम करता है)। धन्यवाद।
वार्विक

जवाबों:


8

ध्यान दें कि आप डेबियन और डेरिवेटिव्स (उबंटू, मिंट,…) द्वारा वितरित पर्ल स्क्रिप्टrename का उपयोग कर रहे हैं । अन्य लिनक्स वितरण एक पूरी तरह से अलग जहाज, और काफी कम उपयोगी, कमांड कहा जाता है rename

y/A-Z/a-z/सीमा में प्रत्येक चरित्र तब्दील Aके माध्यम से Zश्रृंखला में इसी चरित्र में aके माध्यम से z, इसी छोटा अक्षर को यानी ASCII बड़े अक्षरों का। विपरीत अनुवाद करने के लिए, का उपयोग करें y/a-z/A-Z/। एक अन्य तरीका है एक ही आदेश है लिखने के लिए rename '$_ = uc($_)' *ucहै यू pper ase समारोह, और renameआदेश के लिए किए गए परिवर्तन के आधार पर फ़ाइलों का नाम बदलता $_चर।

rename '…' *केवल वर्तमान निर्देशिका में फ़ाइलों का नाम बदल देता है, क्योंकि यही *मेल खाता है। डॉट फाइलें (जिनके नाम से शुरू होती है .) को भी छोड़ दिया जाता है।

यदि आप वर्तमान निर्देशिका में और उपनिर्देशिकाओं में फ़ाइलों का नाम बदलना चाहते हैं, तो आप findवर्तमान निर्देशिका को पुनरावृत्ति करने के लिए कमांड का उपयोग कर सकते हैं । यहां एक कठिनाई है: यदि आप कॉल करते हैं rename, तो यह निर्देशिका और आधार नाम भाग दोनों का नाम बदल देता है। यदि आप renameइसे वापस लेने से पहले किसी निर्देशिका पर कॉल करते हैं ( find -exec rename … {} \;), findतो भ्रमित हो जाता है क्योंकि यह एक निर्देशिका मिली है, लेकिन यह निर्देशिका अब उस समय तक मौजूद नहीं है जब तक इसमें उतरने की कोशिश नहीं की जाती है। आप इस findपर अभिनय करने से पहले किसी डायरेक्टरी को ट्रेस करने के लिए कहकर इसके आसपास काम कर सकते हैं , लेकिन फिर आप नाम बदलने foo/barका प्रयास करते हैं, लेकिन FOO/BARडायरेक्टरी FOOमौजूद नहीं है।

इस कठिनाई से बचने का एक सरल तरीका यह है कि नाम बदलने का कार्य केवल पथ के आधार नाम भाग पर किया जाए। नियमित अभिव्यक्ति ([^/]*\Z)उस पथ के अंतिम भाग से मेल खाती है जिसमें ए नहीं है /

find . -depth -exec rename 's!([^/]*\Z)!uc($1)!e' {} +

खोल zsh नाम बदलने के लिए और अधिक सुविधाजनक सुविधाएँ प्रदान करता है - पर्ल से भी अधिक गूढ़, लेकिन मरोड़ने वाला और अक्सर रचना करने में आसान।

फ़ंक्शन zmvपैटर्न के आधार पर फ़ाइलों का नाम बदल देता है। autoload -U zmvइसे सक्रिय करने के लिए एक बार चलाएं (इस लाइन को अपने में रखें .zshrc)।

पहले तर्क में zmv(बदलने के लिए पैटर्न), आप ज़ीश के शक्तिशाली वाइल्डकार्ड पैटर्न का उपयोग कर सकते हैं । zmv(प्रतिस्थापन पाठ) के दूसरे तर्क में , आप इतिहास संशोधक सहित इसके पैरामीटर विस्तार सुविधाओं का उपयोग कर सकते हैं ।

zmv -w '**/*' '$1$2:u'

स्पष्टीकरण:

  • -w - प्रत्येक वाइल्डकार्ड पैटर्न पर स्वचालित असाइन किए गए संख्यात्मक चर
  • **/*- उपनिर्देशिकाओं में सभी फाइलें, पुनरावर्ती रूप से ( **/उपश्रेणियों के 0, 1 या अधिक स्तरों से मेल खाती हैं)
  • $1 - पहला सांख्यिक चर, यहाँ प्रत्येक पथ के निर्देशिका भाग से मेल खाता है
  • $2:u- दूसरा न्यूमेरिक वैरिएबल, यहां प्रत्येक पथ के आधार नाम भाग का मिलान करते हुए, :uमान को अपरकेस में बदलने के लिए संशोधक के साथ

एक अतिरिक्त बोनस के रूप में, यह परिवेशी लोकेल सेटिंग्स का सम्मान करता है।

यदि आप zmvलिखी गई कमांड के बारे में निश्चित नहीं हैं , तो आप यह -nप्रिंट करने का विकल्प पास कर सकते हैं कि कमांड क्या करेगी और कुछ भी नहीं बदलेगी। आउटपुट की जाँच करें, और यदि आप जो चाहते हैं वह करते हैं, तो -nवास्तव में कार्य किए बिना कमांड को फिर से चलाएं ।


5

गिल्स पोस्ट से चोरी (एक मामूली संपादित के साथ) यहाँ पोस्ट

find <DIR> -depth -type d -exec rename -n 's!/([^/]*/?)$!\U/$1!' {} +


यह पुनरावर्ती कार्य नहीं करता है।
गिल्स एसओ- बुराई को रोकना '

सच। मुझे प्रश्न को ठीक से पढ़ना चाहिए था। मेरा नाम बदलने की आज्ञा नहीं है, लेकिन मेरा मानना ​​है कि यह पुनरावर्ती कार्य करेगा -find <dir> -exec rename 'y/a-z/A-Z/' {} \;
वारविक

यह उस से थोड़ा अधिक जटिल है, क्योंकि आप निर्देशिकाओं का नाम बदल रहे हैं, जबकि findउनमें पुनरावृत्ति हो रही है।
गाइल्स का SO- बुराई पर रोक '

@ गिल्स - ठीक है। थोड़ा शोध करने के बाद, यह प्रतीत होता है कि मुझे -depth विकल्प जोड़ने की जरूरत है ताकि निर्देशिका नाम अंतिम रूप से संभाला जा सके। तो find <dir> -depth -exec rename 'y/a-z/A-Z/' {} \;नाम बदलने निर्देशिका निर्देशिका को संभालना चाहिए। सही बात?
वार्विक

नहीं, यह अभी भी काम नहीं करता है, क्योंकि renameउदाहरण के foo/barलिए परिवर्तन FOO/BARऔर FOOउस बिंदु पर मौजूद नहीं है।
गाइल्स का SO- बुराई पर रोक '23:

2

मैं किसी को भी निर्देशित करना चाहता हूं जो अभी भी इस उत्तर से जुड़ा हुआ है उत्कृष्ट उत्तर के लिए गाइल्स क्वेरनॉट ने इस प्रश्न को दिया था जिसकी आवश्यकता नहीं है find

परिणामी कमांड होगी:

shopt -s globstar
rename -n 'y/a-z/A-Z/' **

लेकिन दौड़ने से पहले कृपया पुराने बैश संस्करणों के बारे में कैविट्स से जुड़े उत्तर पढ़ें।

अंत में अगर कोई सोच रहा है कि y///कमांड क्या करता है perl regex। यहाँ प्रासंगिक प्रलेखन के लिए एक कड़ी है ।


1

find -execdir| नाम बदलने

यह इसे करने के लिए सबसे अच्छा तरीका होगा यदि यह सापेक्ष पथ पागलपन के लिए नहीं थे, क्योंकि यह पर्ल रेगेक्स फू से बचा जाता है केवल बेसन पर कार्य करने के लिए:

PATH="$(echo "$PATH" | sed -E 's/(^|:)[^\/][^:]*//g')" \
  find a -depth -execdir rename 's/(.*)/\U$1/' '{}' \;

-execdirपहले cdकेवल basename पर निष्पादित करने से पहले निर्देशिका में है।

दुर्भाग्य से, मैं उस PATHहैकिंग भाग से छुटकारा नहीं पा सकता हूं , find -execdirयदि आपके पास एक रिश्तेदार पथ है तो कुछ भी करने से इनकार कर देता है PATH...: /ubuntu/621132/why-use-the-execdir-action- है-असुरक्षित गैर-निर्देशिका-जो-है-में-पथ / 1109378 # 1109378


0

निर्देशिका में जाने के बाद इसे आज़माएँ जहाँ आप फ़ाइलों का नाम बदलना चाहते हैं:

for word in `ls -ltr |tail -n +2 |awk '{print $9}'`
do
  a=$(echo $word | tr '[a-z]' '[A-Z]')
  mv $word $a
  echo "Done Successfully"
done

Ls के आउटपुट को पार्स न करें (और पृथ्वी पर आप ls -lकेवल नाम के अलावा अन्य स्तंभों को काटने के लिए क्यों दौड़ेंगे ?) और चर प्रतिस्थापन के आसपास दोहरे उद्धरण चिह्नों का उपयोग करें । आपका कोड अत्यधिक जटिल है और व्हॉट्सएप और अन्य विशेष वर्णों वाले फ़ाइल नामों पर टूट जाता है। का उपयोग करें findया **/उपनिर्देशिकाओं में पुनरावृत्ति करने के लिए, का उत्पादन lsकेवल मानव उपभोग के लिए है।
गिल्स एसओ- बुराई को रोकें '
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.