जवाबों:
rename
उपकरण उबंटू के साथ जहाजों सामान की इस तरह से बहुत गर्म है। आप इस तरह थोड़ा पर्ल अभिव्यक्ति एम्बेड कर सकते हैं:
rename -n 's/.+/our $i; sprintf("AS%d.txt", 1+$i++)/e' *
यह सिर्फ आपको दिखाएगा कि यह क्या करेगा। -n
इसे लाइव-फायर एक्सरसाइज बनाने के लिए निकालें ।
यह मूल रूप से एक चर को किसी न किसी रूप में परिभाषित करके और हमारे द्वारा हिट की गई प्रत्येक फ़ाइल को बढ़ाकर काम करता है। यदि आपके पास 10 से अधिक फाइलें हैं, तो मैं सुझाव देता हूं कि कुछ शून्य-पेडिंग का उपयोग करें sprintf
। निम्नलिखित अच्छा है 999
:
rename -n 's/.+/our $i; sprintf("AS%03d.txt", 1+$i++)/e' *
... लेकिन इसका विस्तार करना काफी आसान है।
@ ओली के उत्तर पर सुधार करने के लिए , अरस्तू पगलतज़िस द्वारा rename
उपकरण संस्करण 1.600 में वास्तव में एक काउंटर बनाया गया है ।$N
तो आप सभी की जरूरत है,
rename 's/AS.*/AS$N/' *
स्थापित करने के लिए,
brew install rename
या स्क्रिप्ट डाउनलोड करें/usr/local/bin/brew
या /usr/bin
) पर निर्देशिका में सहेजेंrename
आपको सीधे असाइन करने देता है $_
, जो इस समस्या के लिए आदर्श है।हालाँकि, हम पर्ल rename
यूटिलिटी को पास करने वाले कोड तर्क अक्सर मिलान और प्रतिस्थापन (के साथ s/
) करते हैं, और यह इस तरह से इस समस्या को हल करने के लिए पूरी तरह से स्वीकार्य है , वास्तव में इस तरह के मामलों की कोई आवश्यकता नहीं है जहां आप वास्तव में परीक्षा नहीं कर रहे हैं या पुराने फ़ाइल नाम के पाठ का पुन: उपयोग करना। rename
आपको बस किसी भी पर्ल कोड के बारे में लिखने देता है , और इसे अंदर एम्बेड करने की आवश्यकता नहीं है s/
/e
। मैं इस तरह से एक कमांड का उपयोग करने का सुझाव देता हूं:
rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' *
या, यदि आप कुछ पात्रों को शेविंग करने की तरह महसूस करते हैं:
rename -n '$_ = sprintf "AS%02d.txt", ++our$i' *
(इसे और भी छोटा बनाया जा सकता है, लेकिन स्पष्टता का त्याग किए बिना नहीं।)
वे दोनों आज्ञाएँ समान कार्य करती हैं। प्रत्येक से पता चलता है कि संचालन का नाम क्या रखा जाएगा। एक बार जब आप एक कोशिश करते हैं और आप परिणामों से खुश होते हैं, तो इसे फिर से -n
विकल्प के बिना चलाएं । लिखित रूप में, यह फ़ाइल नाम का उत्पादन होता है AS01.txt
, AS02.txt
, ..., AS10.txt
, AS11.txt
, और इतने पर। आप उन्हें आवश्यकतानुसार संशोधित कर सकते हैं, तब केवल तभी निकाल सकते हैं -n
जब आपको जो पसंद हो वह देखें।
यदि आप 2 से अधिक चौड़ाई में पैड करना चाहते हैं, तो 2
बड़ी संख्या के साथ बदलें । उदाहरण के लिए, अगर किसी कारण से आप फ़ाइल नाम की तरह चाहता था AS00000000000001.txt
, आप की जगह लेंगे %02d
साथ %014d
। यदि आप बिलकुल भी पेडिंग नहीं करना चाहते हैं - भले ही वह आपकी फ़ाइलों को गैर-संख्यात्मक क्रम में दिखाई दे, जब आप उन्हें बाद में सूचीबद्ध करेंगे! - तो आप %02d
बस के साथ बदल सकते हैं %d
।
यह कैसे काम करता है? आपका शेल *
फ़ाइलों की एक सूची में फैलता है, इससे पहले कि यह rename
कमांड चलाता है । सूची को आपकी वर्तमान स्थानीय सेटिंग के अनुसार lexicographically (यानी, वर्णानुक्रम में) क्रमबद्ध किया गया है। rename
कमांड-लाइन तर्कों के रूप में फ़ाइल नाम प्राप्त करता है और उन्हें सूचीबद्ध किए गए क्रम में संसाधित करता है। अभिव्यक्ति ++$i
चर के वर्तमान मूल्य से एक से अधिक का मूल्यांकन करती है $i
, और चर $i
को उस नए बढ़े हुए मूल्य पर भी सेट करती है । इस मान को पास कर दिया जाता है sprintf
, जो इसे प्रारूपित करता है और इसे अन्य पाठ के अंदर रखता है। यह पाठ सीधे विशेष चर को सौंपा गया है $_
, जो फ़ाइल नाम रखता है। चूंकि rename
प्रक्रियाएं क्रम में फाइलों को तर्क के रूप में पारित करती हैं, इसलिए उन्हें तदनुसार क्रमांकित किया जाता है।
दोनों एक काउंटर चर घोषित करते हैं और बढ़ाते हैं, और दोनों sprintf
अनिवार्य रूप से नए काउंटरनाम के अन्य पाठ में शून्य के साथ बाईं ओर गद्देदार, उस काउंटर के मूल्य को एम्बेड करने के लिए समान रूप से उपयोग करते हैं । (या तो शून्य के साथ पैड करने के तरीके के बारे में जानकारी - और पैडिंग की चौड़ाई को बदलना - यहां तक कि दोनों पर समान रूप से लागू होता है।) कारण यह है कि वे समान हैं कि पुराने उत्तर में विधि वास्तव में सिर्फ यह 1 कर रही है , लेकिन अतिरिक्त चरणों के साथ जो कई समस्याओं के लिए उपयोगी होते हैं लेकिन वास्तव में इसके लिए आवश्यक नहीं है।
तुलना के लिए, यहाँ उस जवाब में दूसरी कमांड क्या दिखती है, अगर मैं यहाँ इस्तेमाल की गई शैली (और 2 की चौड़ाई में पैड करने के लिए संशोधित करूँ, जैसा कि मैंने यहाँ किया है, 3 के बजाय):
rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' *
के बीच हिस्सा s/.+/
और /e
है कि आदेश में अब अभिव्यक्ति मैं करने के लिए आवंटित रूप में ही है $_
(यानी, के दाईं ओर कोड =
इस जवाब में पहली आदेश में ऑपरेटर)।
s/
ऑपरेटर मैच पाठ करने का प्रयास (फ़ाइल नाम अपने खोल से विस्तार है कि *
और कमांड लाइन तर्क जब यह भाग गया के रूप में पारित rename
) एक साथ नियमित अभिव्यक्ति , और प्रदर्शन प्रतिस्थापन। अभिव्यक्ति /
के विभिन्न भागों को अलग करने के लिए एक सीमांकक के रूप में उपयोग किया जा रहा है s
। पहला भाग, .+
नियमित अभिव्यक्ति है; यह किसी भी 1 वर्ण ( .
) से मेल खाता है , और ऐसा एक या अधिक बार ( +
) करता है । चूंकि फ़ाइल नाम कभी खाली नहीं होते हैं - वे हमेशा कम से कम एक वर्ण लंबे होते हैं - यह किसी भी 1 फ़ाइल नाम से मिलान करने का एक तरीका है ।our $i; sprintf "AS%02d.txt", ++$i
। यह नया फ़ाइल नाम बनाता है। आमतौर पर, एक s/
पाठ का उत्पादन करने के लिए उपयोग करता है जो या तो (एक) पाठ की जगह है जो फ़ाइल नाम के सिर्फ एक हिस्से से मेल खाता है, या (ख) मिलान किए गए पाठ के आधार पर किसी तरह से (उदाहरण के लिए, यह एक विशेष चर का उपयोग कर सकता है जैसे $&
कि विस्तार मैच)। इस मामले में, हालांकि, मिलान किए गए पाठ का उपयोग नहीं किया जा रहा है।our $i; sprintf "AS%02d.txt", ++$i
को फ़ाइल नाम के रूप में उपयोग किया जाएगा, कोड के रूप में नहीं चलाया जाएगा। लेकिन /e
अंत में ध्वज उस पाठ को पर्ल स्रोत कोड के रूप में माना जाता है और मूल्यांकन किया जाता है, और ऐसा करने से उत्पन्न मूल्य का उपयोग करता है (इस मामले में, पर्ल के अंतर्निहित sprintf
फ़ंक्शन का रिटर्न मान ) नया फ़ाइल नाम के रूप में।हालाँकि मुझे लगता है कि मैंने जो विधि यहाँ दिखाई है, वह इस समस्या के लिए एक स्पष्ट और सरल तरीका है जो किसी भी विधि के s/
साथ उपयोग करता है /e
, यह उस तकनीक के बारे में पता होना अच्छा है, क्योंकि यह कई अन्य फ़ाइल का नाम बदलने की समस्याओं के अनुकूल है जहाँ सभी या मूल फ़ाइलनाम के भाग की जांच की जाती है और / या बरकरार रखा जाता है। मैं इस ब्लॉग पोस्ट को ओली (जिसने यह भी लिखा है ) के द्वारा सुझाया गया है , जिसमें कुछ ऐसे उदाहरण भी शामिल हैं।
1 तकनीकी तौर पर, कमांड और कमांड के व्यवहार में अंतर होता है । नियमित अभिव्यक्ति में , यह कड़ाई से सच नहीं है कि किसी भी चरित्र से मेल खाता है , क्योंकि यह एक नई रेखा से मेल नहीं खाता है । आप शायद उन में newlines के साथ filenames का उपयोग नहीं करना चाहिए, लेकिन आप कर सकते हैं, और कभी-कभी एक फ़ाइल दुर्घटना से उस रास्ते का नाम हो जाता है। यदि आपको ऐसा लगता है, तो इसके आउटपुट के विपरीत है । मैच को एक नई रेखा बनाने के लिए, ध्वज का उपयोग करें , जो अंत में (साथ ) जाता है। यही है, के बजाय अंत में लिखें ।$_ =
s/
/e
.+
.
rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' $'foo\nbar'
rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' $'foo\nbar'
.
s
e
/se
/e
मान लें कि जिन फ़ाइलों का आप नाम बदलना चाहते हैं ~/Adir
, वे हैं और ये इस फ़ोल्डर की एकमात्र फ़ाइलें हैं, तो:
n=0
for f in $( ls ~/Adir | sort ) ; do
n=$(( n+1 ))
mv -n "$f" "AS${n}.txt"
done
यह स्क्रिप्ट प्रत्येक फ़ाइल को देखती है ~/Adir
और AS1.txt, AS2.txt, ...
यदि फ़ाइल मौजूद नहीं है तो इसका नाम बदल दें (कोई ओवरराइटिंग नहीं होगी)। इसलिए आपको यह सुनिश्चित करना चाहिए कि ये केवल फाइलें हैं ~/Adir
। sort
आदेश सिर्फ मामले में आप फ़ाइलों को प्रारंभिक आदेश को बनाए रखना चाहते है।
rename
prename है। यह बेहतर हो सकता है लेकिन आप इस उत्तर को अधिक मूल्यवान बनाने के लिए इंस्टॉलेशन निर्देश जोड़ना चाह सकते हैं।