फ़ाइलों के संग्रह को एकल नियमित में स्थानांतरित करने से `mv` को कैसे रोकें?


17

मैंने सिर्फ अपने ऑडियो संग्रह का एक छोटा सा हिस्सा खो दिया है, एक बेवकूफ गलती से। :-(
खुशी से मेरे पास हाल ही में बैकअप था, लेकिन यह अभी भी परेशान था। आपके अलावा वास्तव में, शरारत करने वाले दूसरे अपराधी थे mv, जो निम्नानुसार दिखाएंगे:

ऑडियो फाइलों में एक निश्चित योजना थी:

ARTIST - Some Title YY.mp3

YY2-अंकीय वर्ष विनिर्देश कहां है।

mkdir 90<invisible control character>

(इस क्षण तक, मुझे नहीं पता था कि मैंने वास्तव में एक तिहाई अतिरिक्त चरित्र टाइप किया था जो अदृश्य था ...!)
एक निर्देशिका में सभी होने के बजाय, मैं चाहता था कि एक निर्देशिका में सभी 1990 के दशक का संगीत हो। इसलिए मैंने टाइप किया:

find . -name '* 9?.mp3' -exec mv {} 90 \;

ऐसा मुश्किल नहीं है कि विचार प्राप्त करने के लिए क्या हुआ? : ->
(विनाशकारी) परिणाम एक कुंवारी थी खाली निर्देशिका '90 बुलाया कुछ '(के साथ कुछ "अदृश्य" नियंत्रण चरित्र जा रहा है) और एक एकल फाइल तथाकथित' 90 ', ओवरराइट n बार।

सभी फ़ाइलें चला गया। :-(( (जाहिर है)

विश mvकिया है जाएगा जाँच की : समय क्या गंतव्य "फाइल" के हस्ताक्षर (* NIX पर याद में सब कुछ एक फ़ाइल के साथ एक शुरू होता है) d------(जैसे drwxr-xr-x)। और, ज़ाहिर है, चाहे गंतव्य बिल्कुल मौजूद हो। पूर्वोक्त परिदृश्य का एक प्रकार है, जब आप पहले निर्देशिका को भूल जाते हैं mkdir। (लेकिन निश्चित रूप से, आपने मान लिया कि यह वहां है ...)

यहां तक ​​कि हमारे पालतू जानवरों से नफरत करने वाला ओएस राजधानी डब्ल्यू के साथ शुरू होता है । यदि आप इसके लिए पूछें तो आपको गंतव्य का प्रकार (फ़ाइल? निर्देशिका?) निर्दिष्ट करने के लिए भी संकेत मिलता है।

इसलिए, मुझे आश्चर्य है कि अगर हम * NIXers को अभी भी खुद को एक " mvस्क्रिप्टलेट" लिखना है, तो इन प्रकार के सबसे अवांछित आश्चर्य से बचने के लिए।


2
सभी फाइलें नहीं गई थीं। .mp3नाम के साथ कम से कम एक होना चाहिए 90, यह एक हो सकता है जिसके लिए आपके पास बैकअप नहीं था।
एंथन

2
हे, तुम एक निंदनीय भाव मिल गया है, तुम अखरोट! :-P वेल, वह फाइल थी जो "ओपी में एक सिंगल फाइल" बोल्ड प्रिंट में थी। :)
वाक्यविन्यास

2
mvयहाँ समस्या नहीं है, तकनीकी रूप से, यह नहीं जानता कि आप फ़ाइलों की एक श्रृंखला चला रहे हैं। आप mvप्रत्येक फ़ाइल के लिए एक बार चल रहे हैं । इसी तरह find -exec ;काम करता है। यदि आपने find -exec +(कुछ टिप्पणियों में) प्रयोग किया mv होता तो एक से अधिक तर्क मिलते ही चिल्ला उठते।
इटन रीसनर

हालाँकि mvहर एक फाइल के लिए दौड़ना पहली बार में थोड़ा कम सोचा जा सकता है, यह (जैसा कि मैंने पहले कहा था) केवल एकमात्र समाधान हो सकता है एक बार स्रोत फ़ाइल विभिन्न उपनिर्देशिकाओं के बीच बिखरे हुए हैं। मेरे परीक्षण के मामले में, स्रोत फ़ाइलें सभी एक निर्देशिका में थीं इसका मतलब यह नहीं है कि यह मेरा वास्तविक परीक्षण मामला है। यह वास्तव में सिर्फ एक सरलीकरण है, क्योंकि मैं बाद में अपने बारे में आसानी से बता सकता हूं। साथ ही, यह प्रश्नों को उनकी कम लंबाई के कारण पढ़ने में कम समय लेने वाला बनाता है। :)
वाक्यविन्यास

आप इस mvबात की अपेक्षा क्यों करेंगे कि गंतव्य मौजूद है? mv oldfile newfileएक फ़ाइल का नाम बदलने का तरीका है, और यह newfileपहले से मौजूद होने और एक निर्देशिका होने की उम्मीद करने के लिए मूर्खतापूर्ण है ।
बरमार

जवाबों:


37

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

mv somefile somedir/
mv: cannot move ‘somefile’ to ‘somedir/’: Not a directory

यदि निर्देशिका मौजूद है, तो यह फ़ाइल को उस निर्देशिका में ले जाता है।


4
आपको बहुत - बहुत धन्यवाद! यही मेरा भविष्य का जीवन-रक्षक होना चाहिए। मैं आपका आभारी हूं। (एक नोट के रूप में, मेरे एक दोस्त ने कुछ साल पहले बहुत ही गलती की थी, इसलिए मुझे लगता है कि मैं अकेला नहीं हूं।)
वाक्यविन्यास

1
इसके अलावा, कुछ शेल का उपयोग करते समय, आपके पास आपके लिए ऑटो-पूर्ण फ़ाइलनाम के लिए टैब विकल्प होता है। अगर मुझे निर्देशिका नाम याद नहीं है, और आप जैसा हाल ही में कोई गड़बड़ नहीं चाहते हैं, तो बस एक चरित्र में दो या निर्देशिका नाम और हिट टैब । तब आप निश्चित हो सकते हैं, कि यह मौजूद है, क्योंकि ऑटो-कम्प्लीट ने इसे वहाँ रखा है ....
एंडीज़ स्मिथ

@AndyzSmith खैर, यह बहुत अच्छी बात है। आप इसे केवल खान की आदत कह सकते हैं जो कभी जटिल निर्देशिका या पथ के लिए TAB का उपयोग करते हैं, लेकिन 2-अक्षर-प्रकार वाले के लिए नहीं। :) लेकिन यह सोचने के लिए आते हैं ... शायद मुझे वास्तव में बाद के मामले पर भी विचार करना चाहिए। अब से।
वाक्यविन्यास

20

GNU कोरुटिल्स में mvपहले से ही एक विकल्प है जो निर्दिष्ट करता है कि आप एक निर्देशिका में जाना चाहते हैं: -t/ --target-directory। यदि उस विकल्प का तर्क मौजूद नहीं है, mvतो अपनी सभी फ़ाइलों को एक ही फ़ाइल नाम पर ले जाने के बजाय शिकायत करेंगे।

मैंने आपके प्रस्तावक को इस प्रकार लिखा होगा:

find . -name '* 9?.mp3' -exec mv -t 90 {} +

के +बजाय के \;रूप में कई filenames संभव के रूप में एक साथ ग्लोबिंग का उपयोग करें , तेजी से निष्पादन में जिसके परिणामस्वरूप।


धन्यवाद। (उम्मीद है कि यह उन GNU-isms में से एक नहीं है, हालाँकि।)
वाक्यविन्यास

2
@वक्य रचना त्रुटि। यह एक GNUism है। पॉसली:find . -name '* 9?.mp3' -exec sh -c 'exec mv "$@" 90/' sh {} +
स्टीफन चेज़लस

इस सबसे SNEAKY वन-लाइनर के लिए बहुत-बहुत धन्यवाद! जरा सोचो यह एक +5 थे जो मैंने तुम्हें दिए। :) बहुत सारे परीक्षण और त्रुटि अनावश्यक प्रयास करेंगे ।--- और आप अच्छी तरह जानते हैं कि मैंने वह टिप्पणी क्यों की। बस एक मशीन पर होना चाहिए जो कि सीधे पॉसिक्स है (ऐसा बहुत कम ही होता है), और मुझे अगली समस्या वहीं आने वाली है। :)
वाक्यविन्यास

1
@syntaxerror यदि यह उत्तर आपके मुद्दे को हल करता है, तो कृपया एक मिनट का समय लें और वोट काउंट के तहत चेक मार्क को बाईं ओर क्लिक करें, यह सभी को सूचित करेगा कि आपका मुद्दा हल हो गया है और यह तरीका है कि साइट में धन्यवाद व्यक्त किया गया है। मैंने देखा कि आपके केवल कुछ अन्य प्रश्नों के उत्तर स्वीकार किए गए हैं, आप उन लोगों को भी रिवीव करना चाह सकते हैं।
एंथन

नहीं, यह बस उद्देश्य है। जब तक मैं एक उत्तर स्वीकार नहीं करता, तब तक मैं अक्सर कई सप्ताह या कभी-कभी 2 महीने इंतजार कर सकता हूं। कारण यह है कि कुछ बहुत ही जानकार लोगों के पास एक बहुत भरी हुई अनुसूची है और केवल कुछ हफ़्ते के बाद उन्हें (आमतौर पर सबसे अच्छा) उत्तर देने के लिए समय मिल सकता है। इसलिए मुझे हमेशा उनके साथ रुकने के लिए सम्मानजनक लगता है। खैर, और अगर वे वास्तव में नहीं करते हैं, तो मैं निश्चित रूप से चेकमार्क को हिट करने में संकोच नहीं करूंगा। इसके अलावा, मैं यह नहीं देखता कि कुछ लोग एसई + के जायके पर हमेशा इतनी जल्दी क्यों होते हैं। आसान करता है, फेलस। बंदूक मत उछालो। :) यह आपके बॉस का आप पर दबाव नहीं है।
वाक्यविन्यास

10

इसके अतिरिक्त, यदि आप आम तौर पर भविष्य में आकस्मिक ओवरराइट से बचने की योजना बनाते हैं, तो इसके लिए -iविकल्प है mv। मैं व्यक्तिगत रूप से किसी भी कमियों के बारे में नहीं सोच सकता यदि आप

alias mv='mv -i'

अगर आपको कुछ लिखने की जरूरत है, तो बस पास कर दीजिए -f विकल्प को ।

उपनाम केवल तभी प्रभावी होता है जब आप कमांड को एक इंटरैक्टिव शेल में लिखते हैं, न कि मंगलाचरण जैसे मामलों के लिए find। तुम दौड़ सकते थे

find . -name '* 9?.mp3' -exec mv -i {} 90 \;

और तब आपको संकेत दिया जाता कि अगर mvकिसी मौजूदा फ़ाइल को अधिलेखित करने की कोशिश की गई होती।


4
या - जैसा कि आप शायद नहीं जानते थे - के बजाय v \ mv `टाइप करें mv। यह कम ज्ञात "ट्रिक" किसी भी अन्य उपनामों को अनदेखा करने के लिए पूर्ववर्ती बैकस्लैश के साथ कमांड का कारण होगा ।
वाक्यविन्यास

बेशक, अगर आप वास्तव में बात कर रहे हैं find ... -exec mv ..., तो आपको ~/bin/mv(या कुछ अन्य उपयुक्त निर्देशिका) बनाने की आवश्यकता होगी और ऐसा करना होगा /bin/mv -i "$@"- क्योंकि find ... -execयह उपनाम पर नहीं दिखता है।
जी-मैन का कहना है कि 'मोनिका'

इस मामले में, मैं पसंद करूंगा env mv। कम टाइपिंग। :) मेरे स्थानीय कीबोर्ड लेआउट के रूप में SHIFT कुंजी को आगे स्लैश के लिए दबाने की आवश्यकता होती है, मैं हमेशा "स्लैश-कम" संस्करणों (यदि लागू हो) का पक्ष लेगा।
वाक्यविन्यास

1
@syntaxerror: BTW, जब आप टिप्पणी का जवाब देते हैं (एक नई टिप्पणी में), यह लेखक के नाम का उल्लेख करने के लिए पारंपरिक है, "@" से पहले, "@ जी-मैन" के रूप में। इस तरह मैं अधिसूचित हो गया। (मैं आपकी पिछली टिप्पणी का अर्ध-सामयिक तरीके से जवाब देने में सक्षम था क्योंकि मुझे जेनी डी की टिप्पणी से सूचित किया गया था।) आप संपूर्ण नाम (रिक्त स्थान के बिना) का उपयोग कर सकते हैं, उदाहरण के लिए, "@ StéphaneChazelas"। किसी पोस्ट के लेखक को उस पोस्ट पर टिप्पणियों के बारे में स्वचालित रूप से सूचित किया जाता है। इस सहायता पृष्ठ के टिप्पणियों पैराग्राफ में उत्तर देखें ।
जी-मैन ने

1
मुझे क्षमा करें, मैं एक दिन के लिए इंटरनेट-कम था। @ जी-मैन मैं सहमत हूं कि mvशुरुआत में एक स्थान पर एक व्यक्तिगत संस्करण $PATHएक क्लीनर समाधान होगा। दूसरी ओर मैं mvअंतःक्रियात्मक रूप से संवादात्मक खोल में लापरवाह होता हूं (क्योंकि यह तेजी से होता है)। जिस क्षण मैं कुछ अधिक जटिल रचना करता हूं, जैसे कि findएक forलूप, या यहां तक ​​कि एक शेल स्क्रिप्ट, मैं echoयह सुनिश्चित करने के लिए कुछ सूखे रन (उपयोग ) करता हूं कि मैं कुछ तोड़ता नहीं हूं। उन मामलों में मुझे हाथ पकड़ने की ज़रूरत नहीं है mv, क्योंकि मैं पहले से ही इसमें कुछ विचार डाल रहा हूं।
अय्यकत

7

ऊपर दिए गए उत्कृष्ट उत्तरों के अलावा, मैं स्पष्ट करना चाहूंगा कि आपको यह सवाल क्यों नहीं मिला कि फाइलों को स्थानांतरित करना है या नहीं।

यदि आप एक फ़ाइल को किसी नए नाम पर ले जाते हैं, और वह नाम निर्देशिका नहीं है, mvतो आपकी फ़ाइल को नए नाम में बदल दिया जाएगा।

यहां मुद्दा यह है कि आप प्रति फ़ाइल एक बार findनिष्पादित करने के लिए उपयोग कर रहे थे , एक बार सभी फ़ाइलों के लिए नहीं ।mv

यदि, इसके बजाय, आपने किया होता mv *90.mp3 90, तो mvत्रुटि संदेश के साथ विफल हो जाता कि "लक्ष्य फ़ाइल एक निर्देशिका नहीं है"।

लक्ष्य पथ लिखते समय टैब पूर्णता का उपयोग करने के लिए सलाह का एक और टुकड़ा है। यह आपको दिखाएगा कि /लक्ष्य नाम में जोड़कर लक्ष्य एक निर्देशिका है या नहीं । आप यह भी पूछ सकते हैं mv -iकि क्या आप किसी मौजूदा फ़ाइल को अधिलेखित करना चाहते हैं।


यदि, इसके बजाय, आपने किया होता mv *90.mp3 90, तो mv त्रुटि संदेश के साथ विफल हो जाता कि "लक्ष्य फ़ाइल एक निर्देशिका नहीं है"। हाह, हाँ, क्यों इतना जटिल एह? मैं आपकी लाइन का उपयोग करता हूं और मुझे खुशी होगी। केवल इस तुच्छ मामले में, हालांकि। :) क्योंकि यह सामान्य तरीका है जिससे मैं अपने प्रश्न पूछता हूं: मैंने उन्हें सादगी के लिए संकुचित कर दिया था। किसी ने findअभी तक इस पर विचार करने पर आपत्ति नहीं की है कि 90 की फाइलें विभिन्न उपनिर्देशिकाओं के आसपास बिखरी हुई हो सकती हैं जिन्हें मैं "पकड़ना" भी चाहता हूं। यदि और केवल यदि वे हमेशा एक स्रोत निर्देशिका में हों, तो आपकी mvलाइन लागू होगी।
वाक्यविन्यास

@syntaxerror बहुत सच है - मेरा मतलब है कि यह एक उदाहरण के mvरूप में व्यवहार करता है, न कि आपकी पसंद के औजारों की आलोचना के रूप में।
जेनी डी

1
आप शायद के संयोजन कुछ बना सकते हैं findऔर mv, जैसे find /music -type d -exec mv {}/*90.mp3 targetdir\;- लेकिन अब मैं थोड़ा लगता है कि मैं यह कर रहा हूँ overcomplicating, और बस का उपयोग कर -iया -tअधिक कुशल है
जेनी डी

1
@ जेनी: यदि आपका find . -type d -exec mv {}/*9?.mp3 target \;उदाहरण काम करता है, तब भी जोखिम होगा कि mvकमांड mv file targetप्रत्येक निर्देशिका की तरह दिखेगी जिसमें केवल एक *9?.mp3फ़ाइल थी; इसलिए ऐसी सभी फाइलें (अंतिम को छोड़कर) खो जाएंगी।
जी-मैन का कहना है कि 'मोनिका' को

4
@ साइनसैक्टर: मैं पूरे 42,000 लाइन स्क्रिप्ट के बजाय आपकी समस्या के आवश्यक हिस्से को उजागर करने के आपके प्रयास की सराहना करता हूं, जिसमें यह होता है। लेकिन, भले ही आप *.mp3डायरेक्टरी ट्री की सभी फाइलों के लिए कुछ करना चाहते हों , आप कर सकते हैं shopt -s globstarऔर फिर अपनी कमांड को चला सकते हैं **/*.mp3- यह **ए की तरह कार्य करेगा find
जी-मैन का कहना है कि 'मोनिका'

1

वैकल्पिक सामान्य प्रयोजन की रणनीति के रूप में मैं इस तरह के ऑपरेशन को एक अस्थायी स्क्रिप्ट में बदलने का सुझाव देना चाहता हूं। मैं परिणामों को देखना findऔर उन्हें mvहाथ से एक कमांड में बदलना पसंद करता हूं, यह सुनिश्चित करते हुए कि मैं समझता हूं कि मैं निष्पादित होने से पहले क्या कर रहा हूं। जैसे।

find . -name '* 9?.mp3' > tmp
vim tmp

अब मैं फ़ाइलनाम की एक सूची देख सकता हूं और शेल कमांड के रूप में फ़ाइल सामग्री को फिर से लिख सकता हूं।

  • फ़ाइल सामग्री को एक पंक्ति में रखें: ggVGJ
  • प्रारंभ में लगा: Imv [esc]
  • संलग्न: Asomedir/ [esc]
  • फ़ाइल सहेजें। इसे फिर से पढ़ो। सांस लें।
  • source tmpकमांड लाइन पर निष्पादित करें।

यह एक रूढ़िवादी रणनीति है, लेकिन मुझे बहुत बार गलत तरीके से -execया sedआज्ञाओं या गलतफहमी के कारण खोल दिया गया है, और मैं एक धीमी गति से सुसंगत दृष्टिकोण लेना पसंद करता हूं।

दूसरे शब्दों में: मैं उपयोग करने के लिए बहुत कायर हूं -exec


1
आपने :%s/.*/"&"/चरण छोड़ दिया - क्योंकि, इस मामले में, आप जानते हैं कि हर फ़ाइल नाम में कम से कम एक स्थान होता है।
जी-मैन का कहना है कि 'मोनिका' पुनः

1
यदि फ़ाइल नामों में स्थान या अन्य विशेष वर्ण हैं, तो यह आपको काटेगा। आपको उन्हें ठीक से उद्धृत करने की आवश्यकता है। आदेशों की सूची की समीक्षा करने से त्रुटियों को पकड़ने की संभावना नहीं है। उन्हें चलाने से पहले आदेशों की समीक्षा करने के लिए बेहतर तरीके हैं, जैसे कि echo mvइसके बजाय रनिंग mv, और फिर echoयदि आप खुश हैं , तो इसे हटा दें।
गाइल्स का SO- बुराई से दूर रहना '

फ़ाइलनाम-के-रिक्त स्थान जैसी गलती को ठीक करना इस तकनीक के साथ मदद करेगा :-)
टॉम रीस

0

एक अन्य विकल्प:

-n, -no-clobber किसी मौजूदा फ़ाइल को अधिलेखित नहीं करता है

यह के रूप में ही है, लेकिन यह पूछना नहीं होगा, यह विफल हो जाएगा।

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