मेरे फ़ोल्डर के नाम इस तरह से क्यों समाप्त हुए, और मैं इसे स्क्रिप्ट का उपयोग करके कैसे ठीक कर सकता हूं?


15

क्षमा करें, यदि इसका उत्तर कहीं और है, तो मुझे नहीं पता कि मुझे अपनी समस्या की खोज कैसे करनी है।

मैं redhat linux HPC सर्वर पर कुछ सिमुलेशन चला रहा था, और आउटपुट को बचाने के लिए फ़ोल्डर संरचना को संभालने के लिए मेरा कोड एक दुर्भाग्यपूर्ण बग था। फ़ोल्डर बनाने के लिए मेरा matlab कोड था:

folder = [sp.saveLocation, 'run_', sp.run_number, '/'];

sp.run_numberपूर्णांक कहां था मैं इसे एक स्ट्रिंग में बदलना भूल गया, लेकिन किसी कारण से mkdir(folder);(matlab में) चल रहा था। वास्तव में, सिमुलेशन एक अड़चन के बिना चला गया, और डेटा मिलान निर्देशिका में सहेजा गया।

अब, जब फ़ोल्डर संरचना को क्वेर / प्रिंट किया जाता है, तो मुझे निम्नलिखित परिस्थितियां मिलती हैं:

  • जब मैं स्वतः पूर्ण करने का प्रयास करता हूं: run_ run_^A/ run_^B/ run_^C/ run_^D/ run_^E/ run_^F/ run_^G/ run_^H/ run_^I/
  • जब मैं का उपयोग करें ls: run_ run_? run_? run_? run_? run_? run_? run_? run_? run_? run_?
  • जब मैं rsync का उपयोग करके अपने मैक में स्थानांतरित करता हूं तो --progressविकल्प दिखाता है: run_\#003/आदि (मैं मानता हूं) पूर्णांक sp.run_numberको तीन अंकों में गद्देदार से मेल खाता है , इसलिए 10 वां रन हैrun_\#010/
  • जब मैं खोजक में फ़ोल्डर देखता हूं तो देखता हूं run_ run_ run_ run_ run_ run_ run_ run_ run_ run_?
  • इस सवाल को देखते हुए और ls | LC_ALL=C sed -n lमुझे मिलने वाली कमांड का उपयोग करते हुए :
run_$
run_\001$
run_\002$
run_\003$
run_\004$
run_\005$
run_\006$
run_\a$
run_\b$
run_\t$
run_$

मैं cdइनमें से किसी भी प्रतिनिधित्व का उपयोग करके फ़ोल्डर में प्रबंधन नहीं कर सकता ।

मेरे पास इन फ़ोल्डरों में से हजारों हैं, इसलिए मुझे इसे स्क्रिप्ट के साथ ठीक करना होगा। इनमें से कौन सा विकल्प फ़ोल्डर का सही प्रतिनिधित्व है? मैं प्रोग्रामेटिक रूप से इन फ़ोल्डरों को कैसे संदर्भित कर सकता हूं, इसलिए मैं उन्हें बैश स्क्रिप्ट का उपयोग करके ठीक से स्वरूपित नाम के साथ नाम बदल सकता हूं? और मैं जिज्ञासा के लिए अनुमान लगाता हूं कि यह नरक में कैसे हुआ?


4
"जब मैं स्वत: पूर्ण टैब करने का प्रयास करता हूं: ... यदि मैं टाइप करने का प्रयास करता हूं ..." आपके लिए यदि टाइप और स्वत: पूर्ण क्यों नहीं है? इसके अलावा ^Aशाब्दिक रूप से ^पालन नहीं किया जाता है A, लेकिन Ctrl-A (आप इसे Ctrl-V Ctrl-A का उपयोग करके टाइप कर सकते हैं क्योंकि Ctrl-A आम तौर पर शेल के लिए एक शॉर्टकट है)।
मुरु

@ muru जो काम नहीं करता है ... मैं जहाँ तक पहुँचता हूँ run_और मुझे कुछ टाइप करना होता है
Phill

क्षमा करें, इससे पहले कि मैं आपका संपादन
Phill

के संभावित डुप्लिकेट बैश में यूनिकोड फ़ाइल नाम का चयन
muru

9
BTW, "कुछ कारण" क्यों matlab में mkdir ने ऐसा किया है क्योंकि Unix फाइल सिस्टम पर फ़ाइल या निर्देशिका नाम में केवल अमान्य वर्ण NUL और फ़ॉरवर्ड-स्लैश हैं /। कोई अन्य वर्ण मान्य है, जिसमें नियंत्रण वर्ण शामिल हैं। मुझे नहीं पता कि अगर sp.run_number 0 था (तो या तो एक त्रुटि या उत्पादन के साथ गर्भपात हो सकता है run_, क्योंकि NUL बाइट निर्देशिका नाम स्ट्रिंग को समाप्त कर देगी)। बेशक, यह 16-बिट (या उच्चतर) मानों के लिए भी समस्याग्रस्त होगा, जिनमें एनयूएल बाइट था, और मैटलैब चलाने वाले सिस्टम के एंडियन-नेस के अनुसार भी भिन्न होगा।
कैस

जवाबों:


26

निर्देशिकाओं का नाम बदलने के लिए आप पर्ल renameउपयोगिता (उर्फ prenameया file-rename) का उपयोग कर सकते हैं ।

ध्यान दें: यह renameसे util-linux, या किसी अन्य संस्करण से भ्रमित नहीं होना है ।

rename -n 's/([[:cntrl:]])/ord($1)/eg' run_*/

यह ord()उस वर्ण के लिए क्रमिक संख्या के साथ फ़ाइल नाम में प्रत्येक नियंत्रण-वर्ण को बदलने के लिए पर्ल के फ़ंक्शन का उपयोग करता है । जैसे ^A1 बन जाता है, ^B2 बन जाता है, आदि।

-nविकल्प एक सूखी रन क्या दिखाने के लिए है rename जाएगा अगर आप इसे करते हैं। -vवास्तव में नाम बदलने के लिए इसे निकालें (या इसे वर्बोज़ आउटपुट के साथ बदलें)।

eमें संशोधक s/LHS/RHS/egआपरेशन कारणों आरएचएस (प्रतिस्थापन) पर्ल कोड के रूप में निष्पादित करने के लिए पर्ल, और $1एलएचएस से मिलान किया डेटा (नियंत्रण चरित्र) है।

यदि आप फ़ाइल नाम में शून्य-गद्देदार संख्या चाहते हैं, तो आप के ord()साथ संयोजन कर सकते हैं sprintf()। जैसे

$ rename -n 's/([[:cntrl:]])/sprintf("%02i",ord($1))/eg' run_*/ | sed -n l
rename(run_\001, run_01)$
rename(run_\002, run_02)$
rename(run_\003, run_03)$
rename(run_\004, run_04)$
rename(run_\005, run_05)$
rename(run_\006, run_06)$
rename(run_\a, run_07)$
rename(run_\b, run_08)$
rename(run_\t, run_09)$

उपरोक्त उदाहरण काम करते हैं अगर और केवल अगर sp.run_number आपकी मैटलैब लिपि में 0..26 की सीमा होती है (तो यह निर्देशिका नामों में नियंत्रण-वर्ण का उत्पादन करता है)।

किसी भी 1-बाइट वर्ण (यानी 0..255 से) से निपटने के लिए, आप उपयोग करेंगे:

rename -n 's/run_(.)/sprintf("run_%03i",ord($1))/e' run_*/

अगर sp.run_number> 255 हो सकता है, तो आपको unpack()इसके बजाय पर्ल के फ़ंक्शन का उपयोग करना होगा ord()। मुझे नहीं पता कि कैसे matlab एक स्ट्रिंग में एक अनकंटेन्ड इंट को आउटपुट करता है, इसलिए आपको प्रयोग करना होगा। perldoc -f unpackविवरण के लिए देखें।

उदाहरण के लिए निम्नलिखित 8-बिट और 16-बिट अहस्ताक्षरित मानों को अनपैक करेंगे और उन्हें 5-अंकीय चौड़े पर शून्य-पैड करेंगे:

 rename -n 's/run_(.*)/sprintf("run_%05i",unpack("SC",$1))/e' run_*/

विवरण के लिए धन्यवाद! मैं इसे -nविकल्प के साथ परखने की कोशिश कर रहा हूं , लेकिन यह मुझे इसका एक अवैध विकल्प बता रहा है - संस्करण की जानकारी मुझे देती है, rename from util-linux 2.23.2इसलिए मुझे यकीन है कि इसका समान कार्य नहीं हो रहा है
Phill

3
यही कारण है कि मैंने उपयोगिता के पर्ल संस्करण को निर्दिष्ट किया है renameutil-linuxके renameबहुत अलग, अब तक कम करने में सक्षम है, और कमांड लाइन विकल्पों असंगत हैं। यदि आप डेबियन या समान चला रहे हैं, तो file-renameपैकेज स्थापित करने का प्रयास करें । अन्यथा अपने distro के लिए उपयुक्त पैकेज स्थापित करें। यह पहले से ही स्थापित किया जा सकता है, चलाने की कोशिश करें prenameया file-renameइसके बजाय बस rename
कैस

हाँ मुझे लगा कि मामला यही था। मैं देखूंगा कि क्या मुझे उनमें से एक काम मिल सकता है। मुझे मदद करने के लिए समय निकालने के लिए फिर से धन्यवाद!
फिल

11

और मैं जिज्ञासा के लिए अनुमान लगाता हूं कि पहली जगह में यह कैसे हुआ?

folder = [sp.saveLocation, 'run_', sp.run_number, '/'];

sp.run_numberपूर्णांक कहां था मैं इसे एक स्ट्रिंग में बदलना भूल गया, लेकिन किसी कारण से चल रहा है mkdir(folder); (मतलब में) फिर भी सफल हुए।

तो, ऐसा प्रतीत होगा कि mkdir([...])मैटलैब एक स्ट्रिंग के रूप में फाइलनेम बनाने के लिए एरे के सदस्यों को सम्मिलित करता है। लेकिन आपने इसे इसके बदले एक नंबर दिया, और संख्याएं वही हैं जो कंप्यूटर पर अक्षर वास्तव में हैं। तो, जब sp.run_numberथा 1, तो यह आपको मूल्य के साथ चरित्र दिया 1, और फिर मूल्य के साथ चरित्र 2, आदि।

वे नियंत्रण वर्ण हैं, उनके पास मुद्रण योग्य प्रतीक नहीं हैं, और उन्हें टर्मिनल पर प्रिंट करने के अन्य परिणाम होंगे। इसलिए इसके बजाय, वे अक्सर विभिन्न प्रकार के पलायन से प्रतिनिधित्व करते हैं: \001(ओक्टल), \x01(हेक्स), ^Aमूल्य के लिए चरित्र के लिए सभी सामान्य प्रतिनिधित्व हैं 1। मान शून्य वाला वर्ण थोड़ा अलग है, यह NUL बाइट है जिसका उपयोग C में और Unix सिस्टम कॉल में एक स्ट्रिंग के अंत को चिह्नित करने के लिए किया जाता है।

यदि आप 31 से अधिक हो गए हैं, तो आपको मुद्रण योग्य वर्ण दिखाई देने लगेंगे, 32 स्थान है (हालांकि बहुत दृश्यमान नहीं है), 33 = !, 34 = "आदि।

इसलिए,

  • run_ run_^A/ run_^B/- पहले run_एक शून्य बाइट के साथ एक से मेल खाती है, स्ट्रिंग वहां समाप्त होती है। अन्य दिखाते हैं कि आपका शेल कंट्रोल कोड प्रदर्शित करने का उपयोग करना पसंद करता है ^A। अंकन इस तथ्य पर भी संकेत देता है कि संख्यात्मक मान 1 के साथ चार्ट में प्रवेश किया जा सकता है Ctrl-A, हालांकि आपको शेल को एक नियंत्रण चरित्र के रूप में व्याख्या करने की आवश्यकता नहीं है, लेकिन शाब्दिक के रूप में, Ctrl-V Ctrl-Aकम से कम बैश में ऐसा करना चाहिए।

  • ls: run_ run_? run_?- lsयह टर्मिनल पर अनपेक्षित वर्णों को प्रिंट करना पसंद नहीं करता है, यह उन्हें प्रश्नवाचक चिन्ह से बदल देता है।

  • rsync: run_\#003/- यह मेरे लिए नया है, लेकिन विचार समान है, बैकस्लैश एक पलायन को चिह्नित करता है, और बाकी चरित्र का संख्यात्मक मान है। मुझे ऐसा प्रतीत होता है कि यहाँ की संख्या अष्टक में है, और अधिक समान है \003

  • कमांड का उपयोग ls | LC_ALL=C sed -n l... run_\006$ run_\a$ run_\b$ run_\t$- \a, \bऔर \tक्रमशः अलार्म (घंटी), बैकस्पेस और टैब के लिए सी एस्केप हैं। उनके पास संख्यात्मक मान 7, 8 और 9 हैं, इसलिए यह स्पष्ट होना चाहिए कि वे क्यों आते हैं \006। उन सी एस्केप का उपयोग नियंत्रण पात्रों को चिह्नित करने का एक और तरीका है। अनुगामी डॉलर के चिह्न रेखा के सिरों को चिह्नित करते हैं।

के रूप में cd, मेरी मान्यताओं को सही मानते हुए, cd run_उस एक एकल निर्देशिका को एक अजीब अनुगामी चरित्र के बिना cd run_?जाना चाहिए , और एक त्रुटि देनी चाहिए क्योंकि प्रश्न चिह्न एक चमकता हुआ चरित्र है जो किसी भी एकल वर्ण से मेल खाता है, और कई मिलान फ़ाइल नाम हैं, लेकिन cdकेवल एक उम्मीद करता है।

इनमें से कौन सा विकल्प फ़ोल्डर का सही प्रतिनिधित्व है?

सब के सब, एक अर्थ में ...

बैश में, आप विशेष वर्णों का प्रतिनिधित्व करने के लिए उद्धरणों के अंदर \000और बाहर \x00भाग सकते हैं $'...', इसलिए $'run_\033(अष्टक) या $'run_\x1b'निर्देशिका के साथ चरित्र मान 27 (जो ईएससी होता है ) के अनुरूप है। (मुझे नहीं लगता कि बैश दशमलव संख्या के साथ बच का समर्थन करता है।)

कैस के जवाब में उन लोगों का नाम बदलने की स्क्रिप्ट है, इसलिए मैं वहां नहीं जाऊंगा।


यदि यह GNU है ls, तो गैर-मुद्रण वर्ण कैसे दिखाए जाते हैं, यह नियंत्रित करने के लिए -b/ --escapeऔर --quoting-style=या QUOTING_STYLEपर्यावरण चर सहित कुछ विकल्प हैं। मुझे नहीं लगता कि इसे बनाने के लिए कोई विकल्प है, हालांकि यह चरित्र संस्करणों पर ऑक्टेल से बचना पसंद करता है।
टोबी स्पाईट

3

सबसे गलत यह होगा कि गलत फ़ाइल नाम और सही फ़ाइल नाम उसी वातावरण में बनाया जाए, जहाँ पर दुर्घटना हुई है, और फिर फ़ोल्डर को सही नामों पर स्थानांतरित / नाम बदलें।

मौजूदा नामों के बीच टकराव से बचने के लिए दूसरे गंतव्य फ़ोल्डर का बेहतर उपयोग करें।

./saveLocationA/wrongname1 -> ./saveLocationB/correctname1
./saveLocationA/wrongname2 -> ./saveLocationB/correctname2
./saveLocationA/wrongname3 -> ./saveLocationB/correctname3

यदि संभव हो तो, मैं स्क्रिप्ट को ठीक करना पसंद करूंगा और बस इसे फिर से चलाऊंगा; कुछ अजीब बग पोस्टमार्टम को ठीक करने में संभवतः अधिक लागत आती है और नई समस्याओं का परिचय दे सकता है।

सौभाग्य!

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