एक्सटेंशन के अलावा अंडरस्कोर के साथ फ़ाइल नाम में डॉट्स को बदलना


9

क्या कोई फ़ाइल नाम बदलने का सुझाव दे सकता है:

head.body.date.txt

सेवा:

head_body_date.txt

क्या यूनिक्स में नाम बदलने के लिए एक ही लाइन स्टेटमेंट है ?


9
क्या आप मानते हैं कि .tar.gzयह एक विस्तार है? इसके अलावा, यू एंड एल में आपका स्वागत है!
EKons

2
क्या वास्तव में लिनक्स के विपरीत यूनिक्स का मतलब है? कौन सा यूनिक्स?
terdon

1
स्पष्ट उत्तर है mv head.body.date.txt head_body_date.txt। यदि आपके पास अन्य प्रतिबंध या वास्तविक उदाहरण हैं, तो कृपया इन के साथ अपने प्रश्न को अपडेट करें। जैसा कि यह अब खड़ा है, यह स्पष्ट नहीं है कि प्रश्न उस स्पष्ट नाम के साथ एक फ़ाइल को संदर्भित करता है, एक एकल निर्देशिका जहां सभी फ़ाइलों का एक विशेष प्रारूप होता है, या यदि आप किसी विशेष नाम के लिए एक निर्देशिका पदानुक्रम खोजना चाहते हैं और इन्हें बदलते हैं।
Kusalananda

जवाबों:


9

फ़ाइल नाम पर परिवर्तन करें, और रूपांतरण के लिए पैरामीटर विस्तार का उपयोग करें:

for f in *.*.*.txt; do i="${f%.txt}"; echo mv -i -- "$f" "${i//./_}.txt"; done

पैरामीटर विस्तार पैटर्न, फ़ाइल नाम ( ) में s के साथ ${f//./_}सभी को प्रतिस्थापित करता है ।._$f

ऊपर एक सूखी चलाने के लिए, वास्तविक नाम बदलने जगह लेने के लिए, हटा देगा echo:

for f in *.*.*.txt; do i="${f%.txt}"; mv -i -- "$f" "${i//./_}.txt"; done

यदि आप किसी भी एक्सटेंशन से निपटना चाहते हैं, न कि केवल .txt:

for f in *.*.*.*; do pre="${f%.*}"; suf="${f##*.}"; \
                     echo mv -i -- "$f" "${pre//./_}.${suf}"; done

echoवास्तविक कार्रवाई के लिए जाँच हटाने के बाद :

for f in *.*.*.*; do pre="${f%.*}"; suf="${f##*.}"; \
                     mv -i -- "$f" "${pre//./_}.${suf}"; done

सामान्य, डॉट्स की मनमानी संख्या के लिए, कम से कम एक:

for f in *.*; do pre="${f%.*}"; suf="${f##*.}"; \
                 mv -i -- "$f" "${pre//./_}.${suf}"; done

वहाँ एक सामान्य तरीका है अगर वहाँ डॉट्स की एक मनमानी संख्या है?
सिप्रियन टॉमोयागॉ

1
@CiprianTomoiaga डो:for f in *.*; do ...; done
हेमायल

मैं *.*उदाहरण में सीधे पैटर्न डालने का सुझाव दे सकता हूं , क्योंकि अब कोड ऐसा लगता है कि यह केवल निश्चित संख्या में डॉट्स के साथ काम करता है।
लकक्चु

@ilkachachu मेला काफी, संपादित।
हेमायल

बहुत बहुत धन्यवाद हेमे, यह मेरे लिए काम किया। और कुछ सीख!
एसजी

4

perlआधारित के साथrename

$ rename -n 's/\.[^.]+$(*SKIP)(*F)|\./_/g' head.body.date.txt 
rename(head.body.date.txt, head_body_date.txt)
  • \.[^.]+$(*SKIP)(*F) इस पैटर्न को छोड़ें और वैकल्पिक मैचों की तलाश करें
  • |\./_/gसभी के .साथ बदलें_

या, नकारात्मक रूपांतर का उपयोग कर

$ rename -n 's/\.(?![^.]+$)/_/g' head.body.date.txt 
rename(head.body.date.txt, head_body_date.txt)

एक बार यह ठीक हो जाए, तो -nविकल्प को हटा दें


3
rename 's/\.(?=[^.]*\.)/_/g' *.txt

रेगेक्स रिप्लेसमेंट का उपयोग करता है, लेकिन .फाइलनेम (नॉन-कैप्चरिंग लाहहेड) के सभी अंतिम उदाहरणों को खोजने और उन्हें बदलने के लिए _। करने के लिए generalises *.*यदि आप चाहें।

(इस विशेष संस्करण के renameमाध्यम से स्थापित किया जा रहा है लगता है util-linux)। मैं उपयोग कर रहा हूँ Ubuntu 12.04(हाँ, गंभीर रूप से पुराना मशीन)।


2

bash:

old=head.body.date.txt oldb=${old%.*} olde=${old##*.} ; \
mv -- "$old" "${oldb//./_}.${olde}"

(1) आपको mv --"पुराने" फ़ाइलनामों के साथ रक्षा करने के लिए उपयोग करना चाहिए , जो शुरू होता है -। (2) आपको "पुराने" फ़ाइलनामों से बचने के लिए $oldउद्धरण ( "$old") में रखना चाहिए , जिसमें रिक्त स्थान या वर्ण हैं जो शेल (जैसे *और ?) के लिए विशेष हैं । (3) आपका उत्तर कुछ हद तक पैथोलॉजिकल मामले में विफल रहता है जिसमें विस्तार में अंडरस्कोर होता है: का head.body.date.t_xtनाम बदल दिया जाता है head_body_date_t.xt
स्कॉट

@ सच, ​​धन्यवाद अब उल्लिखित तीनों मदों के अनुसार कोड को बदल दिया गया है।
४:०४

1

उपयोग करना mv, sedऔर revएक पंक्ति में:

mv "head.body.date.txt" "$(echo head.body.date.txt | rev | sed 's/\./_/2g' | rev)"

यदि आप इसे txtवर्तमान रेप में सभी फ़ाइलों पर लागू करना चाहते हैं , तो ग्लब्स का उपयोग करना मुश्किल लगता है कि कैसे mvकाम करता है, लेकिन आप forएक-लाइनर में एक लूप कर सकते हैं :

for file in *.txt; do mv "$file" "$(echo $file | rev | sed 's/\./_/2g' | rev)"; done

थोड़ा लंबा है, लेकिन आप अपने पाश में कई पैटर्न से मेल खा सकते हैं!


2
(१) अर्घ्य! मत करो $(ls …); बस करो for file in *.txt। (2) आपको अधिक उद्धरण का उपयोग करना चाहिए mv "$file" "$(…)":।
स्कॉट

शुक्रिया स्कॉट, विधिवत रूप से विख्यात और संपादित! मैं अभी भी शेल में एक युवा हूं, कृपया कोमल
वैलेंटाइन बी।

renameकई अन्य लोगों की तरह उनके जवाबों में सुझाए गए शब्दों का उपयोग करते हुए ध्वनि में सरलता होती है ...
वैलेंटाइन बी।

-1
 mv head.body.date.txt head_body_date.txt

यह एक बार में एक फ़ाइल के लिए उतना ही सरल है। आप यह निर्दिष्ट नहीं करते हैं कि आप इसे किसी निर्देशिका में या पूरी निर्देशिका में पुनरावर्ती रूप से करना चाहते हैं, ताकि आपका सबसे सुविधाजनक, त्वरित समाधान हो।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.