UTF-8 के साथ `cut -c` (` -characters`) का उपयोग नहीं कर सकते हैं?


15

आदेश cutमें विकल्प -cके साथ बाइट्स के बजाय, वर्णों पर काम करने का विकल्प होता है -b। लेकिन यह en_US.UTF-8स्थानीय में काम करने के लिए नहीं लगता है :

दूसरा बाइट दूसरा ASCII वर्ण देता है (जो UTF-8 में केवल एक ही एन्कोड किया गया है):

$ printf 'ABC' | cut -b 2          
B

लेकिन UTF-8 लोकेल में तीन ग्रीक गैर-एएससीआईआई पात्रों में से दूसरा नहीं देता है:

$ printf 'αβγ' | cut -b 2         
�

यह ठीक है - यह दूसरी बाइट है
इसलिए हम इसके बजाय दूसरे चरित्र को देखते हैं:

$ printf 'αβγ' | cut -c 2 
�

जो टूटा हुआ दिखता है।
कुछ प्रयोगों के साथ, यह पता 3-4चलता है कि सीमा दूसरा वर्ण दिखाती है:

$ printf 'αβγ' | cut -c 3-4
β

लेकिन यह बाइट्स 3 से 4 के समान ही है:

$ printf 'αβγ' | cut -b 3-4
β

तो UTF-8 -cके -bलिए इससे अधिक नहीं है ।

मुझे उम्मीद है कि UTF-8 के लिए लोकल सेटअप सही नहीं है, लेकिन तुलना में, उम्मीद के मुताबिक wcकाम करता है;
इसका उपयोग अक्सर बाइट्स को गिनने के लिए किया जाता है, विकल्प -c( --bytes) के साथ। (भ्रमित करने वाले विकल्प नामों पर ध्यान दें।)

$ printf 'αβγ' | wc -c
6

लेकिन यह विकल्प के साथ वर्ण भी गिन सकता है -m( --chars), जो सिर्फ काम करता है:

$ printf 'αβγ' | wc -m
3

तो मेरा विन्यास ठीक लगता है - लेकिन कुछ खास है cut

शायद यह UTF-8 का समर्थन नहीं करता है? लेकिन ऐसा लगता है कि यह मल्टी-बाइट पात्रों का समर्थन करता है, अन्यथा इसे समर्थन करने की आवश्यकता नहीं होती है -bऔर -c

तो क्या गलत हुआ? और क्यों?


स्थानीय सेटअप utf8 के लिए सही लगता है, जहाँ तक मैं बता सकता हूँ:

$ locale
LANG=en_US.UTF-8
LANGUAGE=en_US
LC_CTYPE=en_US.UTF-8
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

इनपुट, बाइट बाईट:

$ printf 'αβγ' | hd 
00000000  ce b1 ce b2 ce b3                                 |......|
00000006

दिलचस्प! ऐसा लगता है कि जैसे -cकोड का उपयोग कर रहा है -b। क्या आपके पास स्रोत कोड पर एक नज़र है? शायद आप एक संकेत पा सकते हैं कि -cवास्तव में किसके लिए है।
माइक्स

जवाबों:


13

आपने यह नहीं कहा कि cutआप किसका उपयोग कर रहे हैं, लेकिन जब से आपने जीएनयू के लंबे विकल्प का उल्लेख किया है, --charactersमैं मान लूंगा कि यह वही है। उस स्थिति में, इस मार्ग परinfo coreutils 'cut invocation' ध्यान दें :

‘-c character-list’
‘--characters=character-list’

वर्ण-सूची में सूचीबद्ध पदों में केवल वर्णों को मुद्रित करने के लिए चयन करें। अभी के लिए भी उतना ही-b , लेकिन अंतर्राष्ट्रीयकरण उसको बदल देगा।

(महत्व दिया)

फिलहाल, जीएनयू cutहमेशा एकल-बाइट "वर्ण" के संदर्भ में काम करता है, इसलिए आपके द्वारा देखा जाने वाला व्यवहार अपेक्षित है।


POSIX द्वारा समर्थन -bऔर -cविकल्प दोनों की आवश्यकता होती है - उन्हें GNU में नहीं जोड़ा गया cutक्योंकि इसमें मल्टी-बाइट का समर्थन था और उन्होंने ठीक से काम किया था, लेकिन POSIX- अनुरूप इनपुट पर त्रुटियों से बचने के लिए। -cकुछ अन्य cutकार्यान्वयनों में भी ऐसा ही किया गया है , हालांकि फ्रीबीएसडी और ओएस एक्स कम से कम नहीं हैं।

यह ऐतिहासिक व्यवहार है -c-bबाइट भूमिका संभालने के लिए नव जोड़ा गया था ताकि -cमल्टी-बाइट पात्रों के साथ काम कर सकें। शायद कुछ वर्षों में यह लगातार वांछित के रूप में काम करेगा, हालाँकि प्रगति बिल्कुल ठीक नहीं है (यह पहले ही एक दशक से अधिक हो चुका है)। GNU विकल्प को अभी cut तक लागू नहीं करता-n है, भले ही यह ऑर्थोगोनल है और संक्रमण की सहायता करने का इरादा है। पुरानी स्क्रिप्ट के साथ संभावित संगतता समस्याएं हैं, जो एक चिंता का विषय हो सकता है, हालांकि मुझे निश्चित रूप से नहीं पता कि इसका कारण क्या है।


1
अच्छा कार्य। आप GNU के trडॉक्स में भी इसी तरह की टिप्पणी पाएंगे । और यहां tarतक कि जब तक मैं गलत नहीं करता। मुझे लगता है कि यह एक बड़ी परियोजना है।
मोकेसर

क्या यूनिकोड प्रोबेलम के लिए कोई वर्कअराउंड है cut? उदाहरण के लिए, पैच किए गए स्रोतों को डाउनलोड करना कहां संभव है cut? या फिर एक और उपयोगिता का उपयोग करना अधिक आसान होगा? ( grepनीचे दिए गए समाधान सीमा के साथ आसानी से काम नहीं करते हैं 5-8,44-49)
dma_k

2017 के इस लेख को देखें, GNU Coreutils में मल्टीबाइट और यूनिकोड समर्थन को जोड़ने के लिए ऑन-गोइंग प्रयास के बारे में रैंडम नोट्स और पॉइंटर्स : " crashcourse.housegordon.org/coreutils-multanyte-support.html
myrdd

आप cut -cयहाँ कुछ विकल्प पा सकते हैं : superuser.com/questions/506164/…
18/18

5

colrm( util-linuxअधिकांश वितरणों पर पहले से ही स्थापित होना चाहिए) का हिस्सा लगता है कि अंतर्राष्ट्रीयकरण को बेहतर ढंग से संभालना है:

$ echo 'αβγ' | colrm 3
αβ
$ echo 'αβγ' | colrm 2
α

नंबरिंग से सावधान रहें: colrm Nकॉलम को हटाए जाएंगे N, अक्षरों को प्रिंट करेंगे N-1

( क्रेडिट )


2

चूंकि कई grepकार्यान्वयन मल्टीबाइट-जागरूक हैं, इसलिए आप grep -oकुछ उपयोगों का अनुकरण करने के लिए भी उपयोग कर सकते हैं cut -c

$ echo Τηεοδ29 | grep -o '^..'
Τη
$ echo Τηεοδ29 | egrep -o '^..' | grep -o '.$'
η

cutश्रेणियों को अनुकरण करने के लिए अवधि की संख्या को समायोजित करें ।

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