गैर-अस्सी (यूनिकोड) पात्रों के बारे में ट्रे को कैसे अवगत कराया जाए?


36

मैं फ़ाइल (UTF-8) से कुछ वर्णों को निकालने का प्रयास कर रहा हूं। मैं trइस उद्देश्य के लिए उपयोग कर रहा हूं :

tr -cs '[[:alpha:][:space:]]' ' ' <testdata.dat 

फ़ाइल में कुछ विदेशी अक्षर होते हैं (जैसे "Латвийская" या "àé")। trउन्हें समझ में नहीं आता है: यह उन्हें गैर-अल्फ़ा मानता है और हटा भी देता है।

मैंने अपनी कुछ स्थानीय सेटिंग बदलने की कोशिश की है:

LC_CTYPE=C LC_COLLATE=C tr -cs '[[:alpha:][:space:]]' ' ' <testdata.dat
LC_CTYPE=ru_RU.UTF-8 LC_COLLATE=C tr -cs '[[:alpha:][:space:]]' ' ' <testdata.dat
LC_CTYPE=ru_RU.UTF-8 LC_COLLATE=ru_RU.UTF-8 tr -cs '[[:alpha:][:space:]]' ' ' <testdata.dat

दुर्भाग्य से, इनमें से कोई भी काम नहीं किया।

मैं trयूनिकोड को कैसे समझ सकता हूं ?

जवाबों:


29

यह एक ज्ञात ( 1 , 2 , 3 , 4 , 5 , 6 ) GNU कार्यान्वयन की सीमा है tr

यह उतना नहीं है कि यह विदेशी , गैर-अंग्रेजी या गैर-एएससीआईआई वर्णों का समर्थन नहीं करता है, लेकिन यह मल्टी-बाइट वर्णों का समर्थन नहीं करता है।

उन सिरिलिक वर्णों को ठीक माना जाएगा, यदि iso8859-5 (एकल-बाइट प्रति वर्ण) वर्ण सेट में लिखा गया हो (और आपका स्थान उस वर्ण का उपयोग कर रहा था), लेकिन आपकी समस्या यह है कि आप UTF-8 का उपयोग कर रहे हैं जहाँ गैर- ASCII वर्ण 2 या अधिक बाइट्स में एन्कोड किए गए हैं।

जीएनयू को एक योजना मिली (यह भी देखें ) कि इसे ठीक करने के लिए काम चल रहा है लेकिन अभी तक नहीं हुआ है।

FreeBSD या Solaris trमें समस्या नहीं है।


इस समय के अधिकांश मामलों के लिए tr, आप GNU sed या GNU awk का उपयोग कर सकते हैं जो बहु-बाइट वर्णों का समर्थन करते हैं।

उदाहरण के लिए, आपका:

tr -cs '[[:alpha:][:space:]]' ' '

लिखा जा सकता है:

gsed -E 's/( |[^[:space:][:alpha:]])+/ /'

या:

gawk -v RS='( |[^[:space:][:alpha:]])+' '{printf "%s", sep $0; sep=" "}'

निचले और ऊपरी मामले में परिवर्तित करने के लिए ( tr '[:upper:]' '[:lower:]'):

gsed 's/[[:upper:]]/\l&/g'

( lयह एक लोअरकेस है L, 1अंक नहीं )।

या:

gawk '{print tolower($0)}'

पोर्टेबिलिटी के लिए, perlएक और विकल्प है:

perl -Mopen=locale -pe 's/([^[:space:][:alpha:]]| )+/ /g'
perl -Mopen=locale -pe '$_=lc$_'

यदि आप जानते हैं कि डेटा को एक एकल-बाइट वर्ण सेट में दर्शाया जा सकता है, तो आप इसे चारसेट में संसाधित कर सकते हैं:

(export LC_ALL=ru_RU.iso88595
 iconv -f utf-8 |
   tr -cs '[:alpha:][:space:]' ' ' |
   iconv -t utf-8) < Russian-file.utf8

1
मैंने tr के बारे में जानकारी के कारण आपका प्रश्न स्वीकार कर लिया है। मैंने समस्या को हल कर लिया है, और इसे हल करने के तरीके के बारे में प्रश्न को हटा दिया है (इसलिए tr की तलाश करने वाले लोग केवल tr के बारे में जानकारी पाएंगे, कुछ मनमानी समस्या नहीं)। यदि आप कृपया समाधान भी निकाल सकते हैं, क्योंकि अब इसकी आवश्यकता नहीं है, तो मैं आभारी रहूंगा।
मैथ्यू रॉक

3
@MatthewRock मैंने इसे रखा है, लेकिन इसे फिर से तैयार किया है और एक शब्द के रूप में और अधिक सामान्य बना दिया है जो एक ही समस्या वाले लोगों के लिए उपयोगी होगा।
स्टीफन चेज़लस

आपको यह अंदाजा नहीं है कि सिरिलिक (कस्टम रूप से) आईएसओ 8859-5 में एन्कोडेड है? क्या आपने कभी भी यूनिकोड में एक रूसी पाठ देखा है?
इंनिस मिस्सी

9
@IncnisMrsi, यहां जो कुछ भी मायने रखता है वह यह है कि ISO 8859-5 उन सिंग-बाइट वर्णों में से एक है जिसमें उन सिरिलिक वर्ण हैं। चाहे वह व्यापक उपयोग में हो या न हो, यहाँ अप्रासंगिक है। यदि आपके पास KOI-R या विंडो -1251 चारसेट के साथ एक लोकेल है, तो सभी तरीकों से इसका उपयोग करें।
स्टीफन चेजलस

वेब पर @IncnisMrsi रूसी लगभग हमेशा UTF-8 (या कभी-कभी विंडोज -1251 में) में एन्कोडेड है, लेकिन केवल इसलिए कि हमने कई सिंगल-बाइट एन्कोडिंग के दर्द को जल्दी महसूस किया है। यहाँ एक (गैर-कार्यात्मक) एन्कोडिंग स्विचर के साथ एक प्राचीन (लगभग 1998) वेब पेज है: sch57.ru/collect
एलेक्स शापिलकिन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.