एक्सटेंशन बदलने के लिए mv के साथ कई फ़ाइलों का नाम बदलें


27

मैं उनके विस्तार को बदलने के लिए फ़ाइलों का नाम बदलना चाहता हूं, प्रभावी रूप से पूरा करना चाहता हूं

mv *.txt *.tsv

लेकिन ऐसा करते समय मुझे मिलता है:

* .tsv एक निर्देशिका नहीं है

मुझे यह कुछ अजीब लगता है कि पहले 10 गूगल हिट शो mvको इस तरह से काम करना चाहिए।


आपको यह स्पष्ट करना चाहिए कि आप उन फ़ाइलों का नाम कैसे बदलना चाहते हैं।
तोटर

1
वैसे मेरे पास * .gappedPeak के एक्सटेंशन वाली फाइलें हैं और उनका नाम बदलकर * .bed करना चाहते हैं। वे सभी एक ही निर्देशिका में हैं यह बहुत सरल होना चाहिए, लेकिन मुझे सफल होने के लिए लूप के लिए पूर्ण आवश्यकता थी
सैंडर वान डेर ज़ीव

आपको Google पर जो मिला वह MSDOS पर लागू होता है मुझे लगता है।
Tiktak

@ देवनबुल का वैकल्पिक समाधान वास्तव में मददगार है
lucasvw

जवाबों:


22

जब आप आदेश जारी करते हैं:

mv *.txt *.tsv

शेल, मान लें कि यदि कोई मेल खाने वाली फाइलें (निर्देशिकाओं सहित) हैं, तो वाइल्डकार्ड का विस्तार करें । फ़ाइलों की सूची कार्यक्रम के लिए यहां दी गई है । यदि कोई मैच नहीं मिला है तो अनएक्सपैंडेड वर्जन पास किया जाता है।mv

दोबारा: शेल पैटर्न का विस्तार करता है, न कि कार्यक्रम का।


उदाहरणों का भार शायद सबसे अच्छा तरीका है, इसलिए यहाँ हम चलते हैं:

उदाहरण 1:

$ ls
file1.txt file2.txt

$ mv *.txt *.tsv

अब mvलाइन पर क्या होता है कि शेल*.txt मिलान वाली फाइलों तक फैल जाता है। जैसे कि ऐसी कोई *.tsvफाइल नहीं है जिसे बदला नहीं गया है।

mvआदेश में कहा जाता है दो विशेष तर्क के साथ :

  • argc: कार्यक्रम सहित तर्कों की संख्या।
  • argv: पहली प्रविष्टि के रूप में कार्यक्रम सहित तर्कों की एक सरणी।

उपरोक्त उदाहरण में यह होगा:

 argc = 4
 argv[0] = mv
 argv[1] = file1.txt
 argv[2] = file2.txt
 argv[3] = *.tsv

यह mvदेखने के लिए कि क्या अंतिम तर्क है, कार्यक्रम *.tsvएक निर्देशिका है। जैसा कि यह नहीं है, कार्यक्रम जारी नहीं रह सकता है क्योंकि यह फ़ाइलों को संक्षिप्त करने के लिए डिज़ाइन नहीं किया गया है। (आमतौर पर सभी फाइलों को एक में स्थानांतरित करें।) न ही एक निर्देशिका पर निर्देशिका बनाएं।

परिणामस्वरूप यह गर्भपात करता है और त्रुटि की रिपोर्ट करता है:

mv: target ‘*.tsv’ is not a directory

उदाहरण 2:

अब अगर आप इसके बजाय कहते हैं:

$ mv *1.txt *.tsv

mvकमांड के साथ क्रियान्वित किया जाता है:

 argc = 3
 argv[0] = mv
 argv[1] = file1.txt
 argv[2] = *.tsv

अब, फिर mvसे देखें कि क्या *.tsvमौजूद है या नहीं। जैसा कि यह फ़ाइल file1.txtको स्थानांतरित नहीं किया गया है *.tsv। वह यह है: फ़ाइल का नाम बदलकर *.tsvतारांकन चिह्न और सभी के साथ रखा गया है ।

$ mv *1.txt *.tsv
‘file1.txt’ -> ‘*.tsv’

$ ls
file2.txt *.tsv

उदाहरण 3:

यदि आपने इसके बजाय कहा:

$ mkdir *.tsv
$ mv *.txt *.tsv

mvकमांड के साथ क्रियान्वित किया जाता है:

 argc = 3
 argv[0] = mv
 argv[1] = file1.txt
 argv[1] = file2.txt
 argv[2] = *.tsv

जैसा कि *.tsvअब एक निर्देशिका है, फाइलें समाप्त हो जाती हैं।


अब: some_command *.tsvजब वास्तव में वाइल्डकार्ड रखने का इरादा हो तो कमांड का उपयोग करना चाहिए। यदि आप कोई मैच होना चाहिए, तो उद्धृत करके आप वाइल्डकार्ड को विस्तारित होने से रोक सकते हैं। जैसे कहो mkdir "*.tsv"

उदाहरण 4:

यदि आप उदाहरण के लिए करते हैं, तो विस्तार को देखा जा सकता है:

$ ls
file1.txt file2.txt

$ mkdir *.txt
mkdir: cannot create directory ‘file1.txt’: File exists
mkdir: cannot create directory ‘file2.txt’: File exists

उदाहरण 5:

अब: mvकमांड कई फाइलों पर काम कर सकता है और कर सकता है। लेकिन अगर वहाँ अधिक है तो दो अंतिम एक लक्ष्य निर्देशिका होना चाहिए। (वैकल्पिक रूप से आप -t TARGET_DIRविकल्प का उपयोग कर सकते हैं , कम से कम GNU mv के लिए।)

तो यह ठीक है:

$ ls -F
b1.tsv  b2.tsv  f1.txt  f2.txt  f3.txt  foo/

$ mv *.txt *.tsv foo

यहाँ mvबुलाया जाएगा:

 argc = 7
 argv[0] = mv
 argv[1] = b1.tsv
 argv[2] = b2.tsv
 argv[3] = f1.txt
 argv[4] = f2.txt
 argv[5] = f3.txt
 argv[6] = foo

और सभी फाइलें निर्देशिका में समाप्त हो जाती हैं foo


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


30

मुझे पता है कि यह आपके प्रश्न का उत्तर नहीं देता है, लेकिन यदि आप अपने काम के आसपास की लूप की तुलना में फ़ाइलों का नाम बदलने के लिए एक और तरीका तलाश रहे थे, तो इसका उपयोग क्यों करें find? मैंने इस कमांड का उपयोग कई बार बड़ी निर्देशिकाओं में फ़ाइल एक्सटेंशन को बदलने के लिए किया है जिसमें सैकड़ों हजारों फाइलें हैं। यह किसी भी POSIX- अनुरूप प्रणाली पर काम करना चाहिए:

find . -name "*.gappedPeak" -exec sh -c 'mv "$1" "${1%.gappedPeak}.bed"' _ {} \;

कमांड ब्रेकडाउन:

  1. ' .' => खोज पथ वर्तमान निर्देशिका द्वारा शुरू कर रहा है '। '

  2. -name=> सेट मैच का नाम (इस मामले में सभी फाइलें जो समाप्त होती हैं .gappedPeak)

  3. -exec => हर मैच पर निम्न कमांड निष्पादित करें

  4. sh -c => 'निष्पादन' प्रत्येक मैच के लिए एक स्वतंत्र शेल वातावरण बनाता है

  5. mv "$1" "${1%.gappedPeak}.bed"=> mvपहला चर ( $ 1 से चिह्नित ), जो वर्तमान फ़ाइल नाम है, नए नाम पर। यहाँ मैं एक सबस्ट्रिंग मैच और डिलीट करता हूँ; इसलिए पहले संस्करण फिर से लें, $ 1 और स्ट्रिंग से %हटाने के लिए उपयोग करें .gappedPeak.bedअंत में बस शेष चर, जो अब सिर्फ है concatenates , साथ , नए बनाने फ़ाइल नाम।test#.bedtest#.bed

  6. अंडरस्कोर $ 0 के लिए एक प्लेसहोल्डर है

  7. {}प्रत्येक (की जगह *.gappedPeak) फ़ाइल नाम के द्वारा पाया findआदेश, और हो जाता है $ 1 के लिए shआदेश।

  8. \;-execकमांड के अंत को चिह्नित करता है । तुम भी उपयोग कर सकते हैं ';'या ";"

उदाहरण:

[user@before]# ls -lh
total 0
-rw-r--r--. 1 root root 0 Jan 26 11:40 test1.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test2.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test3.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test4.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test5.gappedPeak

[user@after]# ls -lh
total 0
-rw-r--r--. 1 root root 0 Jan 26 11:40 test1.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test2.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test3.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test4.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test5.bed

क्या आप बता सकते हैं कि प्रत्येक भाग क्या करता है?
user1717828

मुझे इस पर खेद है, मैंने अपनी पोस्ट अपडेट की। उम्मीद है की वो मदद करदे।
देवनुल

1
बहुत अच्छे धन्यवाद! एक साथ बैश गाइड और अपने स्पष्टीकरण मैं सब कुछ प्राप्त करने में सक्षम था।
user1717828

कोई बात नहीं। खुशी है कि यह मदद करता है।
देवनुल २ dev'१५

एक जादू की तरह काम करता है। यहाँ कई उप dirs में file.abc-> के लिए एक और सरलीकृत उदाहरण है blub.xyz:find . -name "file.abc" -exec sh -c 'mv "$1" "$(dirname $1)/blub.xyz"' _ {} \;
Mahn

9

mv *.txt *.tsvकाम नहीं करता; mvएक समय में केवल एक फ़ाइल का नाम बदल सकते हैं। आपने स्पष्टीकरणों को गलत समझा है या वे गलत हैं।

mmvऔर renameएक ही बार में कई फ़ाइलों का नाम बदल सकते हैं। लेकिन renameआस-पास के दो संस्करण हैं जिन्हें अलग-अलग कहा जाता है। यहाँ उस बारे में बहुत सारे सवाल होने चाहिए।


1
cyberciti.biz/tips/… Google पर पहली हिट कह रही है कि mv के रूप में अच्छी तरह से काम करना चाहिए, इसलिए मुझे यह बहुत अजीब लगा
Sander Van der Zeeuw

3
@SanderVanderZeeuw मुझे नहीं पता कि आपने वहां क्या पढ़ा है। उदाहरण उपयोग करते हैं rename, नहीं mv
ह्युक लैजिंग

1
क्षमा करें, मैंने गलत HTML चिपकाया है। यह एक udemy.com/blog/rename-a-file-in-linux
Sander Van der Zeeuw

3
@SanderVanderZeeuw शर्मनाक। ये लोग पाठ्यक्रम प्रदान करते हैं? दुर्भाग्य से मुझे वहां संपर्क की संभावना नजर नहीं आ रही है। आप आसानी से जांच सकते हैं कि क्या यह काम करता है। लेकिन mv *.txt *.tsv mv(आमतौर पर) शेल-विस्तारित फ़ाइल नामों को नहीं देखता है *.txtया नहीं करता है *.tsv। इन वाइल्डकार्ड का विस्तार करने वाली फ़ाइलों की संख्या "यादृच्छिक" होगी। एक ही स्थिति जहां यह काम करता है यदि नाम के साथ एक फ़ाइल है *.txtजिसे (शाब्दिक रूप से) नाम दिया जाएगा *.tsv( bashविकल्प के उद्धरण के बिना nullglobसेट नहीं किया जाना चाहिए)।
Hauke ​​Laging

1
या खराब। एक है, तो एक फ़ाइल का नाम जैसे foo.txtऔर एक नामित मौजूदा ऊपर लिख देगा फ़ाइल ...baz.tsvmv *.txt *.tsv.tsv
Runium

4

उदाहरण के लिए, यदि आपके पास asd.txtऔर qwe.txtनिर्देशिका में फ़ाइलों को जब आप आदेश चला mv *.txt *.tsvहै, यह नाम की एक निर्देशिका में इन दो फ़ाइलों को स्थानांतरित करने की कोशिश करता है *.tsv। क्योंकि ऐसी कोई निर्देशिका नहीं है, यह एक त्रुटि देता है।


धन्यवाद, यह आंशिक रूप से स्पष्ट करता है। फिर भी मुझे यह अजीब लगता है कि मैं बहुत सारे मैनुअल पेज देखता हूं जहां वे दावा करते हैं कि mv को कई पर काम करना चाहिए।
सैंडर वान डेर ज़ीव

2

rename(1)

renameलैरी वॉल द्वारा एक पर्ल स्क्रिप्ट है जो पर्ल का निर्माता है। यह एक पर्ल रेगेक्स लेता है और फ़ाइल नाम पर संचालित होता है।

rename 's/\.txt$/.tsv/' *.txt

स्थापना

Debian / Ubuntu

यदि आपको renameडेबियन / उबंटू पर स्थापित करने की आवश्यकता है तो आप कर सकते हैं

sudo apt install rename

0

विचार करने के लिए एक और विकल्प उपयोग कर रहा है:

cp -p *.txt *.tsv
rm -f *.txt
  • पहली पंक्ति ध्वज का उपयोग करके अपनी विशेषताओं को संरक्षित *.txtकरने के लिए सभी फाइलों को कॉपी करती है ।*.tsv-p
  • दूसरी पंक्ति पैटर्न के साथ सभी फाइलों को हटा देती है *.txt
  • इस विधि के लिए आपके पास स्रोत और लक्ष्य फ़ाइलों को अस्थायी रूप से रखने के लिए पर्याप्त डिस्क स्थान की आवश्यकता होती है
  • यह विधि धीमी है, mvजिससे वास्तव में फ़ाइलों को स्थानांतरित किए बिना / निर्देशिका / फ़ाइल नाम बदल जाता है जब तक कि वे एक अलग विभाजन पर न हों।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.