विशेष वर्णों के साथ फ़ाइलों का नाम बदलें (या सही ढंग से प्रदर्शित)


20

मेरे पास निर्देशिकाओं और उपनिर्देशिकाओं का एक समूह है जिसमें विशेष वर्णों वाली फाइलें हैं, जैसे कि यह फाइल:

robbie@phil:~$ ls testsktest.txt 
test?sktest.txt

एक बच निकलने के क्रम का पता लगाएं:

robbie@phil:~$ find testsktest.txt -ls 
424512 4000 -rwxr--r-x   1 robbie   robbie    4091743 Jan 26 00:34 test\323sktest.txt

एकमात्र कारण मैं कंसोल पर उनके नाम भी लिख सकता हूं क्योंकि टैब पूरा होने के कारण। इसका मतलब यह भी है कि मैं उन्हें मैन्युअल रूप से नाम बदल सकता हूं (और विशेष चरित्र को छीन सकता हूं)।

मैंने LC_ALL को UTF-8 में सेट किया है, जो मदद के लिए नहीं लगता है (एक नए शेल पर भी नहीं))

robbie@phil:~$ echo $LC_ALL
en_US.UTF-8

मैं अपने मैक से ssh का उपयोग करके मशीन से जुड़ रहा हूं। यह एक Ubuntu स्थापित है:

robbie@phil:~$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=7.10
DISTRIB_CODENAME=gutsy
DISTRIB_DESCRIPTION="Ubuntu 7.10"

शेल बैश है, TERM को xterm-color में सेट किया गया है।

ये फाइलें काफी समय से हैं, और वे उबंटू की स्थापना का उपयोग करके नहीं बनाई गई हैं। इसलिए मुझे नहीं पता कि सिस्टम एन्कोडिंग सेटिंग्स क्या हुआ करती थी।

मैंने इनकी तर्ज पर चीजों की कोशिश की है:

find . -type f -ls | sed 's/[^a-zA-Z0-9]//g'

लेकिन मुझे ऐसा समाधान नहीं मिल रहा है जो मैं चाहता हूं कि सब कुछ हो:

  1. उन सभी फ़ाइलों को पहचानें जिनके अविभाज्य अक्षर हैं (उपरोक्त उपेक्षा बहुत अधिक है)
  2. निर्देशिका ट्री (पुनरावर्ती) में उन सभी फ़ाइलों के लिए, mv oldname newname निष्पादित करें
  3. वैकल्पिक रूप से, विशेष पात्रों जैसे ä to a (आवश्यक नहीं है, लेकिन भयानक होगा) के अनुवाद की क्षमता

या

  1. इन सभी फ़ाइलों को सही ढंग से प्रदर्शित करें (और जब उन्हें खोलने की कोशिश में कोई त्रुटि न हो)

मेरे पास बिट्स और टुकड़े हैं, जैसे सभी फाइलों पर चलना और उन्हें स्थानांतरित करना, लेकिन फाइलों की पहचान करना और उन्हें एमवी कमांड के लिए सही ढंग से प्रारूपित करना कठिन हिस्सा लगता है।

कोई भी अतिरिक्त जानकारी क्यों वे सही ढंग से प्रदर्शित नहीं करते हैं, या सही एन्कोडिंग का "अनुमान" कैसे किया जाता है, इसका भी स्वागत है। (मैंने convmv की कोशिश की है, लेकिन यह बिल्कुल वैसा नहीं लगता जैसा मैं चाहता हूं: http://j3e.de/linux/convv/ )


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

जवाबों:


21

मुझे लगता है कि आप इस अमान्य चरित्र को देखते हैं क्योंकि नाम में एक बाइट अनुक्रम है जो मान्य UTF-8 नहीं है। ठेठ यूनिक्स फाइल सिस्टम पर फ़ाइल नाम (आपके सहित) बाइट स्ट्रिंग्स हैं, और यह अनुप्रयोगों पर निर्भर है कि क्या एन्कोडिंग का उपयोग करना है। आजकल, UTF-8 का उपयोग करने का एक चलन है, लेकिन यह सार्वभौमिक नहीं है, खासकर उन स्थानों पर जो सादे ASCII के साथ कभी नहीं रह सकते थे और UTF-8 के अस्तित्व में आने से पहले से ही अन्य एन्कोडिंग का उपयोग कर रहे हैं।

LC_CTYPE=en_US.iso88591 lsयह देखने की कोशिश करें कि फ़ाइल का नाम ISO-8859-1 (लैटिन -1) में समझ में आता है या नहीं। यदि ऐसा नहीं होता है, तो अन्य स्थानों का प्रयास करें। ध्यान दें कि यहां केवल LC_CTYPEलोकल सेटिंग मायने रखती है।

UTF-8 लोकेल में, निम्न कमांड आपको वे सभी फाइलें दिखाएगी, जिनका नाम मान्य UTF-8 नहीं है:

grep-invalid-utf8 () {
  perl -l -ne '/^([\000-\177]|[\300-\337][\200-\277]|[\340-\357][\200-\277]{2}|[\360-\367][\200-\277]{3}|[\370-\373][\200-\277]{4}|[\374-\375][\200-\277]{5})*$/ or print'
}
find | grep-invalid-utf8

आप देख सकते हैं कि वे के साथ एक और स्थान में अधिक समझ बनाने के recode या iconv :

find | grep-invalid-utf8 | recode latin1..utf8
find | grep-invalid-utf8 | iconv -f latin1 -t utf8

एक बार जब आप यह निर्धारित कर लेते हैं कि फ़ाइल नामों का एक गुच्छा एक निश्चित एन्कोडिंग (उदाहरण के लिए लैटिन 1) में है, तो उनका नाम बदलने का एक तरीका है

find | grep-invalid-utf8 |
rename 'BEGIN {binmode STDIN, ":encoding(latin1)"; use Encode;}
        $_=encode("utf8", $_)'

यह डेबियन और उबंटू पर उपलब्ध पर्ल नाम बदलें का उपयोग करता है । आप इसे -nदिखा सकते हैं कि यह वास्तव में फाइलों का नाम बदले बिना क्या कर रहा है।


धन्यवाद, मैं आज इनमें से कुछ चीजों को आजमाऊंगा ऐसा लगता है कि यह स्वीकृत उत्तर होगा :)
RobbieV

खोजो | grep '[[: print:]]' कमांड केवल सभी फाइलों को वापस करने के लिए लगता है। क्या UTF-8 को "सामान्य" पात्रों के साथ कई अन्य एन्कोडिंग के साथ संगत नहीं होना चाहिए?
रॉबीवी

@RobbieV: मैंने टाइप किया और अनपेक्षित grep [^[:print:]]वर्णों की खोज की। लेकिन मैंने अभी-अभी GNU grep और अमान्य UTF-8 अनुक्रमों के साथ परीक्षण किया है [^[:print:]](जो समझ में नहीं आता है कि वे अनपेक्षित वर्ण नहीं हैं, वे वर्ण नहीं हैं)। मैंने अपनी पोस्ट को अवैध utf8 दृश्यों के साथ लंबी दूरी की लाइनों के साथ संपादित किया है। ध्यान दें कि मैंने भी recodeऔर iconvउदाहरणों की दिशा तय कर दी है ।
गाइल्स 'एसओ- बुराई को रोकना'

यह पूरी तरह से काम किया। आइकनव एक को छोड़कर सभी कमांड की कोशिश की, और वे सभी उम्मीद के मुताबिक काम करते हैं। शुद्ध जादू!
रॉबीवी

यहां तक ​​कि सुझाव दिया गया कि
लैटिन

1

मुझे पता है कि यह एक पुराना प्रश्न है लेकिन मैं एक समान समाधान के लिए पूरी रात खोज रहा हूं। मुझे कुछ उपयोगी सुझाव मिले, लेकिन उन्होंने ठीक वैसा नहीं किया जिसकी मुझे ज़रूरत थी, इसलिए मुझे उस सही परिणाम को प्राप्त करने के लिए मिश्रण और मैच करना पड़ा जिसकी मुझे तलाश थी

बस विशेष वर्णों को हटाने और उन्हें (।) डॉट के साथ बदलने के लिए

for f in *.txt; do mv "$f" `echo $f | sed "s/[^a-zA-Z0-9.]/./g"`; done

एक क्रोनजॉब में उपयोग करने के लिए मैंने हर मिनट चलाने के लिए निम्न कार्य किया

*/1 * * * * cd /path/to/files/ && for f in *.txt; do mv "$f" `echo $f | sed "s/[^a-zA-Z0-9.]/./g"`; done >/dev/null 2>&1

मुझे आशा है कि किसी को यह उपयोगी लगता है क्योंकि इसने मेरा दिन बना दिया है :)


(1) स्पष्टता के लिए, आप परिवर्तन करना चाह सकते हैं `…`करने के लिए $(…)- देखना यह , यह , और यह । (2) आपको हमेशा अपने शेल चर संदर्भ (जैसे "$f") का उद्धरण देना चाहिए जब तक कि आपके पास कोई अच्छा कारण न हो, और आपको यकीन है कि आप जानते हैं कि आप क्या कर रहे हैं। इस पर भी लागू होता है echo "$f" | sed …। यह संपूर्ण $(…)(या `…`) अभिव्यक्ति पर भी लागू होता है ; यानी, mv "$f" "$(echo "$f" | sed "…")"। … (Cont'd)
स्कॉट

(Cont'd)… (3) आपको कहना चाहिए कि शुरुआत के साथ फाइलनामों से बचाव के लिए । (४) यदि आपके पास “foo ♥ bar.txt” और “foo If bar.txt” नाम की फाइलें हैं, तो यह वसीयत (दोनों को नाम बदलकर "foo.bar.txt" करने की कोशिश करेगा), संभवतः सभी के कारण नष्ट होने वाली फाइलें। (५) पृथ्वी पर आप हर मिनट में एक बार ऐसा क्यों करना चाहेंगे? mv -- "$f" …-
स्कॉट

मेरे पास एक टोरेंट स्क्रिप्ट है जो ऑटो फाइलों को डाउनलोड करती है। और कभी-कभी कुछ फ़ाइलों में वर्ण होते हैं जो अपलोडर को बंद कर देते हैं। तो विशेष वर्णों वाली फ़ाइलों का नाम बदलने से मेरे क्रोन ने मेरी सभी समस्याओं को ठीक कर दिया और अपलोडर अपना काम सुचारू रूप से करता है।
Topps70

तो (यह फाईल था, t था - डाउन_लोड किया गया। कस्टम) (it.fi.le.tha.t.was.down.loaded.ext) में बदल जाता है
Topps70

0

अब, जब आप जानते हैं कि रिमोट एन्ड पर फ़ाइल नाम के लिए कौन सी एन्कोडिंग का उपयोग किया जाता है ("लैटिन 1" - पहले उत्तर के लिए टिप्पणियों के अनुसार), तो आप दूसरे तरीके का भी अनुसरण कर सकते हैं - एक स्थानीय शब्दावलियों को चलाएं और इस तरह से ssh जिस तरह से दूरस्थ फ़ाइल नाम सही तरीके से प्रदर्शित किए जाते हैं (पहले तरीके के बजाय: उनका नाम बदलें)

मेरी तरह , आप स्थानीय रूप से एक टर्मिनल शुरू कर सकते हैं जो उस विशेष एन्कोडिंग में काम करेगा, शायद, इस तरह:

LC_ALL = en_US.latin1 xvt &

xvt अपने टर्मिनल कार्यक्रम के लिए खड़ा है।

शायद, मौजूदा लोकेल को कहा जाता है en_US.iso88591, और नहीं en_US.latin1, जैसा कि मैंने माना।


0

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

अंत में मैंने फ़ाइलज़िला का उपयोग एक SFTP क्लाइंट के रूप में कनेक्ट करने के लिए किया, फाइलों को ब्राउज किया और GUI का उपयोग करके उनका नाम बदल दिया। Filezilla ने डॉगी चार्ज़ को काफी अच्छी तरह से संभाला।

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