मैं फ़ाइलों के एक समूह के लिए एक्सटेंशन का नाम कैसे बदलूं?


479

एक निर्देशिका में, मेरे पास *.htmlफ़ाइलों का एक गुच्छा है । मैं उन सभी का नाम बदलना चाहूंगा*.txt

मैं उसे कैसे कर सकता हूँ? मैं बैश शेल का उपयोग करता हूं।

जवाबों:


382

एक बेहतर समाधान के लिए (बाहरी कॉल के विपरीत केवल बैश कार्यक्षमता के साथ), अन्य उत्तरों में से एक देखें ।


निम्नलिखित को renameप्रोग्राम करने के लिए सिस्टम की आवश्यकता नहीं होगी और (हालांकि आपके पास सिस्टम पर यह अक्सर होता है):

for file in *.html; do
    mv "$file" "$(basename "$file" .html).txt"
done

संपादित करें: जैसा कि टिप्पणियों में कहा गया है, यह उचित उद्धरण (अब ऊपर जोड़ा) के बिना उन में रिक्त स्थान के साथ फ़ाइल नाम के लिए काम नहीं करता है। जब आप जानते हैं कि आपकी फ़ाइल में स्थान नहीं है, तो यह पूरी तरह से काम करेगा लेकिन जब भी आप ऐसा कुछ लिखेंगे, जिसका बाद में पुन: उपयोग किया जा सकता है, तो उचित उद्धरण छोड़ें नहीं।


47
एक विकल्प, बिना बेसन और उद्धरण के साथ: mv "$ {फ़ाइल}" "$ {फ़ाइल /%। Html / .txt" (देखें आदमी बैश, विवरण के लिए पैरामीटर विस्तार)
रोड्रिगो क्वेरो

7
केवल तभी अच्छा है जब फाइलें सभी मौजूदा निर्देशिका में हैं, निश्चित रूप से, क्योंकि बेसनेम पथनाम भाग से स्ट्रिप्स है। बस एक 'खबरदार'!
जोनाथन लेफ़लर

6
यह समाधान खराब है, न केवल इसलिए कि यह धीमा है, बल्कि इसलिए क्योंकि यह उन में रिक्त स्थान के साथ फ़ाइल नाम के साथ काम नहीं करता है। आपको बैश स्क्रिप्ट में उचित उद्धरण देना चाहिए। mv "$ फ़ाइल" "$ (बेसन" $ फ़ाइल ".html)"। txt ज्यादा बेहतर होगा। लेकिन फिर भी, mv "$ files" "$ {files% .html} .txt" ज्यादा बेहतर है।
Balázs Pozsár

8
खिड़कियों में आप बसren *.a *.b
मुहम्मद उमर

2
कम से कम, $()विरासत बैकटिक सिंटैक्स के बजाय POSIX- निर्दिष्ट का उपयोग करें । पठनीयता में सुधार करता है, और वाक्यविन्यास को बहुत कम अस्पष्ट बना देता है जब आपके पास ऐसे चरित्र होते हैं जिन्हें बाद वाले के साथ कमांड प्रतिस्थापन के अंदर शाब्दिक होने के लिए बैकस्लैश-बचना होगा।
चार्ल्स डफी

667

यदि बैश का उपयोग किया जाता है, तो बाहरी कमांड जैसे कि sed, basename, rename, expr, आदि की कोई आवश्यकता नहीं है।

for file in *.html
do
  mv "$file" "${file%.html}.txt"
done

12
और यदि आप उस फ़ाइल एक्सटेंशन को नहीं जानते हैं जिसका आप उपयोग कर सकते हैं "${file%.*}.txt", लेकिन यह फ़ाइलों के लिए खतरनाक हो सकता है / w सब पर एक एक्सटेंशन।
जेस

1
किसी को भी इस काम को करने में परेशानी हो रही है जैसे कि मेरे पास ध्यान दें: ध्यान दें कि $घुंघराले ब्रेसिज़ के अंदर नहीं है!
doug65536

5
मुझे इस उत्तर को स्थायी रूप से पसंदीदा / बुकमार्क करने का एक तरीका चाहिए, मुझे सटीक वाक्यविन्यास कभी याद नहीं है और मैं इसके लिए
गुगली

7
@danip प्रतिशत-संकेत-भीतर-ब्रैकेट अंत से स्ट्रिप्स वर्णों का निर्माण करता है। एक हैश-भीतर-ब्रैकेट निर्माण भी है जो शुरुआत से ही स्ट्रिप्स वर्ण करता है। इसे जांचें: tldp.org/LDP/abs/html/parameter-substitution.html#PSUB2

4
एक और स्टैक एक्सचेंज उत्तर (जो मुझे नहीं मिल सकता है!) ने यह सुझाव दिया, लेकिन --"ऑपरेटर": mv - "$ फ़ाइल" "$ {फ़ाइल% .html} .txt" का उपयोग करके भी। यह ऑपरेटर फ़ाइल नाम को रोकता है जो इसके साथ शुरू होता है। a '-' से तर्कों के रूप में mv द्वारा पार्स किया जा रहा है।
rcreswick

191
rename 's/\.html$/\.txt/' *.html

वास्तव में आप क्या चाहते हैं।


मुझे नहीं लगता कि आप बैश में शाब्दिक रीगेक्स का उपयोग कर सकते हैं जैसे आप सुझाव देते हैं - आप किस शेल का उपयोग कर रहे हैं?
डेवआर

1
मैं एक मैक टर्मिनल का उपयोग कर रहा हूं
bmw0128

यहाँ उबंटू पर नाम बदलने के संस्करण के लिए मैन पेज है: unixhelp.ed.ac.uk/CGI/man-cgi?rename
Amber

कुछ सिस्टम पर नाम बदलना एक कमांड है। मेरे पास एक पर्ल स्क्रिप्ट है (मूल रूप से पहली कैमल बुक से) जो काम करती है। एक ही नाम का एक GNU प्रोग्राम भी है जो लगभग एक ही काम करता है। मेरे मैक में एक सिस्टम-प्रदत्त 'नाम बदलें' कमांड नहीं है - या यह मेरे पैट पर नहीं है (जो मध्यम व्यापक है)।
जोनाथन लेफ़लर

Homebrew में एक नाम बदलने का सूत्र है।
Revprez

112

इसने मेरे लिए OSX पर .txt से .txt_bak तक काम किया

find . -name '*.txt' -exec sh -c 'mv "$0" "${0%.txt}.txt_bak"' {} \;

4
लाइनक्स में भी ठीक काम करता है।
डिजीट

यह इस बिंदु के अलावा है, लेकिन आपसे बस जाने के .txtलिए .txt_bak_bak
संक्षिप्त करना है

3
यह पुनरावर्ती नाम बदलने के लिए अच्छा है
leachryanb

महान! (उबंटू 16.04 के तहत) मेरा व्यावहारिक उपयोग मामला, सभी .scssका नाम बदलकर .sass(इन-प्लेस रूपांतरण के बाद ...):find . -name '*.scss' -exec sh -c 'mv "$0" "${0%.scss}.sass"' {} \;
फ्रैंक नॉक

2
इसने +6000 फाइलों के साथ काम किया, नाम बदला "तर्क सूची बहुत लंबी थी"
टोनी क्रोनिन

94

आप उपयोग करना चाहते हैं rename:

rename -S .html .txt *.html

यह ठीक करता है कि आप क्या चाहते हैं - यह से विस्तार बदल जाएगा .htmlकरने के लिए .txtसभी मिलते-जुलते फ़ाइलों के लिए *.html

नोट: ग्रेग हेविल सही ढंग से बताते हैं कि यह बैश बिलिन नहीं है; और एक अलग लिनक्स कमांड है। यदि आपको लिनक्स पर कुछ चाहिए तो यह ठीक काम करना चाहिए; यदि आपको कुछ और क्रॉस-प्लेटफ़ॉर्म की आवश्यकता है, तो अन्य उत्तरों में से एक पर एक नज़र डालें।


7
यद्यपि यह एक अच्छा समाधान है, renameकार्यक्रम संबंधित नहीं है bashऔर सभी प्लेटफार्मों पर भी उपलब्ध नहीं है। मैंने इसे केवल लिनक्स पर देखा है।
ग्रेग हेवगिल

15
"।
अंबर

8
सही सिंटैक्स वह rename -S .html .text *.htmlजगह है जिसके लिए -Sखड़ा है--subst-all
मारेक सेबरा

8
शराब की भठ्ठी स्थापित नाम
निक

4
@GregHewgill का नाम मैक ओएस के लिए HomeBrew
CodeBrauer



9

यह सबसे पतला समाधान है जो मैंने पाया है कि OSX और लिनक्स पर काम करता है, और यह अच्छी तरह से काम भी करता है!

find . -name "*.js" -exec bash -c 'mv "$1" "${1%.js}".tsx' - '{}' \;

और गिट के साथ:

find . -name "*.js" -exec bash -c 'git mv "$1" "${1%.js}".tsx' - '{}' \;


8

यहाँ पुनर्नामित आदेश का एक उदाहरण दिया गया है:

rename -n s/\.htm$/\.html/’ *.htm

-N का मतलब है कि यह एक टेस्ट रन है और वास्तव में किसी भी फाइल को नहीं बदलेगा। यह आपको उन फ़ाइलों की एक सूची दिखाएगा, जिन्हें यदि आपने -n हटा दिया है, तो उसका नाम बदल दिया जाएगा। उपरोक्त मामले में, यह .htm की फ़ाइल एक्सटेंशन से वर्तमान निर्देशिका में सभी फ़ाइलों को .html में बदल देगा।

यदि उपरोक्त परीक्षण रन का आउटपुट ठीक लगा, तो आप अंतिम संस्करण चला सकते हैं:

rename -v s/\.htm$/\.html/’ *.htm

-V वैकल्पिक है, लेकिन इसे शामिल करने के लिए यह एक अच्छा विचार है क्योंकि यह एकमात्र रिकॉर्ड है जो आपके पास परिवर्तन के नाम से होगा जो कि नीचे दिए गए नमूना आउटपुट में दिखाया गया है:

$ rename -v 's/\.htm$/\.html/' *.htm
3.htm renamed as 3.html
4.htm renamed as 4.html
5.htm renamed as 5.html

बीच में मुश्किल हिस्सा नियमित अभिव्यक्ति के साथ एक पर्ल प्रतिस्थापन है, जो नीचे दिया गया है:

rename -v s/\.htm$/\.html/’ *.htm

6

इस सवाल में स्पष्ट रूप से बैश का उल्लेख है, लेकिन अगर आपके पास ZSH उपलब्ध है तो यह बहुत आसान है:

zmv '(*).*' '$1.txt'

यदि आप मिलते हैं zsh: command not found: zmvतो बस चलाएं:

autoload -U zmv

और फिर दोबारा कोशिश करें।

Zmv के बारे में इस मूल लेख के लिए धन्यवाद ।


4

किसी और की वेबसाइट के क्रॉल होने के बाद, मैंने उपनिर्देशिका के एक विस्तृत वृक्ष के बीच .html एक्सटेंशन को गायब करने वाली हजारों फ़ाइलों को समाप्त कर दिया।

उन सभी को एक शॉट में नाम बदलने के लिए, जिनके पास पहले से ही एक .html एक्सटेंशन है (उनमें से अधिकांश में कोई भी नहीं था) को छोड़कर, इसके लिए यह आवश्यक है:

cd wwwroot
find . -xtype f \! -iname *.html   -exec mv -iv "{}"  "{}.html"  \;  # batch rename files to append .html suffix IF MISSING

ओपी के मामले में, मैं इसे थोड़ा संशोधित कर सकता हूं, केवल * .txt फ़ाइलों का नाम बदलने के लिए, जैसे:

find . -xtype f  -iname *.txt   -exec filename="{}"  mv -iv ${filename%.*}.{txt,html}  \; 

टूट गया (हथौड़ा!):

-iname * .txt
- मतलब केवल .txt में पहले से ही समाप्त हो रही फ़ाइलों पर विचार करें

mv -IV "{} {txt, एचटीएमएल}।" - जब खोज गुजरता {} फ़ाइल नाम के रूप में एक, $ {। फ़ाइल नाम% *} अपने basename किसी भी विस्तार के बिना करने के लिए मानकों के रूप में निकालता है mvबैश को दो मापदंडों के रूप में फिर से लिखने के लिए {txt, html} लेता है ताकि अंतिम कमांड निम्नानुसार चले:mv -iv "filename.txt" "filename.html"

हालांकि फिक्स की जरूरत है: फ़ाइल नाम में रिक्त स्थान के साथ काम करना


4

आदेशmmv (एक दूसरे में हजारों की संख्या में) फ़ाइलों की एक बड़ी संख्या पर बहुत कुशलता से यह काम पूरा कर रहा है। उदाहरण के लिए, सभी .xmlफ़ाइलों को .htmlफ़ाइलों का नाम बदलने के लिए , इसका उपयोग करें:

mmv ";*.xml" "#1#2.html"

;पथ से मेल खाएगी, *फ़ाइल नाम से मेल खाते हैं, और ये भी कहा जाता है #1और #2प्रतिस्थापन नाम पर।

execया पाइप पर आधारित उत्तर या तो बहुत धीमी गति से या बहुत बड़ी संख्या में फाइलों में विफल रहे।



3

पार्टी करने में थोड़ी देर हो गई। आप इसे xargs के साथ कर सकते हैं:

ls *.html | xargs -I {} sh -c 'mv $1 `basename $1 .html`.txt' - {}

या अगर आपकी सभी फाइलें किसी फोल्डर में हैं

ls folder/*.html | xargs -I {} sh -c 'mv $1 folder/`basename $1 .html`.txt' - {}

3
सं पार्स न करेंls । यह आदेश हास्यास्पद है: यह बेकार के साथ lsसीधे ग्लोब का उपयोग करने के बजाय एक ग्लोब का उपयोग करता है । यह रिक्त स्थान, उद्धरण और (उद्धरण चिह्नों की कमी के कारण) युक्त ग्लोब पात्रों के साथ टूट जाएगा।
१२:०२ पर ganiourf_gniourf

FYI करें, आपके लिंक किए गए लेख में एक अपडेट किया गया नोट है जो कहता है कि नया LS 'सही ढंग से "शेल बच जाता है" अगर टर्मिनल पर प्रिंट किया जाता है। " आपकी बात अभी भी अंगूठे का एक अच्छा नियम है।
कैटैस्टिक वॉयज

3

एक बार में कई एक्सटेंशन संशोधित करने का यह एक अच्छा तरीका है:

for fname in *.{mp4,avi}
do
   mv -v "$fname" "${fname%.???}.mkv"
done

नोट: एक ही होने के लिए विस्तार आकार में सावधान रहें (???)


2

अच्छा और सरल!

find . -iname *.html  -exec mv {} "$(basename {} .html).text"  \;

2

यदि आप पेरल को पसंद करते हैं, तो एक छोटी सी पेरेल स्क्रिप्ट है (मूल रूप से लैरी वॉल, जिसे पेरल के निर्माता ने लिखा है) जो आप यहाँ चाहते हैं, वही करेंगे: tips.webdesign10.com/files/rename.pl.txt

अपने उदाहरण के लिए निम्नलिखित कार्य करना चाहिए:

rename.pl 's/html/txt/' *.html

2
इस सवाल का जवाब पहले ही दिया जा चुका है और बहुत समय पहले स्वीकार किया जा चुका है और ऐसा नहीं लगता है कि आपका उत्तर पहले से कही गई बातों से ज्यादा कुछ भी लाता है।
क्रिस्टोफ़ेलेक

1
+1 चूंकि यह एक लैरी वॉल स्क्रिप्ट थी (रॉबिन बार्कर द्वारा संशोधित)। अंतिम उपलब्ध यूआरएल यह है: tips.webdesign10.com/files/rename.pl.txt
loretoparisi

1

इसी तरह जो पहले सुझाया गया था, वह यह है कि मैंने यह कैसे किया:

find . -name '*OldText*' -exec sh -c 'mv "$0" "${0/OldText/NewText}"' {} \;

मैंने पहले सत्यापन किया

find . -name '*OldText*' -exec sh -c 'echo mv "$0" "${0/OldText/NewText}"' {} \;

1

एक पंक्ति, कोई छोर नहीं:

ls -1 | xargs -L 1 -I {} bash -c 'mv $1 "${1%.*}.txt"' _ {}

उदाहरण:

$ ls
60acbc4d-3a75-4090-85ad-b7d027df8145.json  ac8453e2-0d82-4d43-b80e-205edb754700.json
$ ls -1 | xargs -L 1 -I {} bash -c 'mv $1 "${1%.*}.txt"' _ {}
$ ls
60acbc4d-3a75-4090-85ad-b7d027df8145.txt  ac8453e2-0d82-4d43-b80e-205edb754700.txt

एक बैश-केवल रास्ता दिखाने के लिए +1 जो मौजूदा एक्सटेंशन के मिलान पर निर्भर नहीं करता है। यह किसी भी इनपुट एक्सटेंशन के लिए काम करता है, चाहे वह 3 वर्ण लंबा हो या 4 वर्ण लंबा या अधिक
साइप्रियन टोमायागो

0

दुर्भाग्य से यह मामूली रूप से करने के लिए तुच्छ नहीं है। आप शायद expr जादू की एक बिट की जरूरत है।

for file in *.html; do echo mv -- "$file" "$(expr "$file" : '\(.*\)\.html').txt"; done

एक बार जब आप खुश होते हैं तो इसे हटा दें जो आप चाहते हैं।

संपादित करें: basename शायद इस विशेष मामले के लिए थोड़ा अधिक पठनीय है, हालांकि exprसामान्य रूप से अधिक लचीला है।


हालांकि यह सवाल का सबसे अच्छा जवाब नहीं हो सकता है, यह मेरे लिए था! मुझे एक स्ट्रिंग को पूरे पथ में केवल नाम बदलने की आवश्यकता थी, न कि केवल फ़ाइल नाम। पोस्ट करने का शुक्रिया!
डोनट

0

यहाँ मैं क्या करने के लिए .edgeफ़ाइलों का नाम बदलने के लिए इस्तेमाल किया है.blade.php

for file in *.edge; do     mv "$file" "$(basename "$file" .edge).blade.php"; done

आकर्षण जैसा काम करता है।


0

आप बैश में एक समारोह भी बना सकते हैं, इसे .bashrcया कुछ और जोड़ सकते हैं और फिर इसे जहां चाहें उपयोग कर सकते हैं।

change-ext() {
    for file in *.$1; do mv "$file" "$(basename "$file" .$1).$2"; done
}

उपयोग:

change-ext css scss

समारोह में कोड का स्रोत: https://stackoverflow.com/a/1224786/6732111


0

किसी भी अन्य पैकेज के बिना वर्तमान निर्देशिका और उप निर्देशिका के तहत सभी फ़ाइलों के लिए फ़ाइल एक्सटेंशन का नाम बदलें (केवल शेल स्क्रिप्ट का उपयोग करें):

  1. rename.shनिम्नलिखित कोड के साथ वर्तमान निर्देशिका के तहत एक शेल स्क्रिप्ट बनाएं :

    #!/bin/bash
    
    for file in $(find . -name "*$1"); do
      mv "$file" "${file%$1}$2"
    done
  2. इसे चलाएं ./rename.sh .old .new

    उदाहरण के लिए। ./rename.sh .html .txt

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