Linux में "wc -c" और "wc -m" कमांड


24

मेरे पास एक पाठ फ़ाइल है, इसकी सामग्री है:

i k k

जब मैं wc -mइस फ़ाइल पर वर्ण संख्या गिनने के लिए उपयोग करता हूं , तो परिणाम 7 होता है

प्रश्न 1: लेकिन मुझे 7 क्यों मिले, क्या मुझे " 6 " नहीं मिलना चाहिए कि यह " एंड-ऑफ-लाइन " चरित्र को गिना जाए ?

प्रश्न 2: वास्तव में कैसे wc -mकाम करता है ?

प्रश्न 3: जब मैं wc -cबाइट संख्याओं का उपयोग करता हूं (), तो मेरे पास एक ही परिणाम है wc -m, इसलिए दो अलग-अलग विकल्प होने का क्या मतलब है ? वे ठीक वैसा ही काम करते हैं न? यदि नहीं, तो क्या अंतर है और कैसे wc -cकाम करता है?



1
अगर आप विंडोज से CRLF लाइन एंडिंग के साथ फाइल करते हैं तो आपको 7 भी मिल सकते हैं
क्रिस एच

जवाबों:


36

आपके पास वास्तव में केवल 6 वर्ण होने चाहिए। दौड़ने की कोशिश करो

cat -A filename

अपनी फ़ाइल के गैर-मुद्रण वर्ण देखने के लिए। आपके पास कुछ अतिरिक्त होना चाहिए। अगर मैं आपकी तरह एक फाइल बनाता हूं, तो मैं देखता हूं

i k k$

क्या आपने स्पेस दिया? इससे 7 i k k $बनेंगे: या हो सकता है कि यह एक नई रेखा है:

i k k$
$

जो 7 भी है

जैसा आप कहें

wc -m

वर्ण और मायने रखता है

wc -c

बाइट्स गिनता है। यदि आपके सभी वर्ण ASCII वर्ण सेट का हिस्सा हैं, तो प्रति वर्ण केवल 1 बाइट होगा, इसलिए आपको दोनों आदेशों से समान संख्या प्राप्त होगी।

गैर ASCII वर्ण वाली फ़ाइल पर प्रयास करें:

$ echo ك > testfile
$ wc -m testfile
2 testfile
$ wc -c testfile
3 testfile

अहा! अब पात्रों की तुलना में अधिक बाइट्स।


3
मैंने " कैट-ए " कमांड का इस्तेमाल किया और मैंने पाया कि " एंड-ऑफ-लाइन " चरित्र ( $ ) से पहले मेरे पास एक स्थान है । इसलिए मुझे ६ की जगह why मिलीं। धन्यवाद, " कैट-ए " ने बहुत मदद की।
SWIIWII

2
@SWIIWII हाँ मैंने अपने उत्तर में सिर्फ इतना जोड़ा कि जैसा मैंने सोचा था कि शायद वैसा ही होगा :)
ज़न्ना

1
newline वर्ण भी गिना गया था। यहां तक ​​कि अगर यह गैर-दृश्यमान है, तो यह अभी भी एक चरित्र है और फ़ाइल में डेटा के रूप में गिना जाता है। बिल्ली का अच्छा उपयोग-वैसे। एक बार भी ऐसा करने के लिए hexdump या xxd का उपयोग कर सकते हैं
Sergiy Kolodyazhnyy

@ शेर हाँ, और cat -Aवह भी दिखाएगा। मैंने अपने जवाब में कहा, धन्यवाद :)
Zanna

@SWIIWII ने `likethis`पठनीय बनाने के लिए backticks में कोड डाला , इसे बोल्ड मत बनाओ
phuclv

2
$ locale charmap
UTF-8

मेरे वर्तमान परिवेश में, वर्ण सेट UTF-8 है, अर्थात्, वर्ण प्रति वर्ण 1 से 4 बाइट्स के साथ एन्कोडेड हैं (हालांकि क्योंकि UTF-8 की मूल परिभाषा वर्ण कोड 0x7fffffff तक की है, अधिकांश उपकरण UTF- को पहचानते हैं 6 बाइट्स के 8 बाइट सीक्वेंस)।

उस वर्ण सेट में, यूनिकोड के सभी वर्ण उपलब्ध हैं, एक aबाइट मान 65 के रूप में कोडित है, 3 बाइट्स 228 185 149 के éरूप में और उदाहरण के लिए दो बाइट अनुक्रम 195 169।

$ printf 乕 | wc -mc
  1       3
$ printf a | wc -mc
  1       1

अभी व:

$ export fr_FR.iso885915@euro
$ locale charmap
ISO-8859-15

मैंने अपने परिवेश को संशोधित किया है, जहाँ अब सेट किया गया ISO-8859-15 (भाषा, मुद्रा प्रतीक, तिथि प्रारूप जैसी अन्य चीज़ों को भी संशोधित किया गया है, उन क्षेत्रीय सेटिंग्स के संग्रह को लोकेल के रूप में संदर्भित किया जा रहा है )। मुझे इसके वातावरण में एक नया टर्मिनल एमुलेटर शुरू करने की आवश्यकता है ताकि इसके चरित्र को नए स्थान पर प्रस्तुत किया जा सके।

ISO-8859-15 एक एकल बाइट वर्ण सेट है जिसका अर्थ है कि इसमें केवल 256 वर्ण हैं (वास्तव में इससे भी कम वास्तव में कवर किए गए हैं)। यह विशिष्ट वर्ण सेट पश्चिमी यूरोप की भाषाओं के लिए उपयोग किया जाता है क्योंकि यह अपनी अधिकांश भाषाओं (और यूरो प्रतीक) को कवर करता है।

इसमें aयूटीएफ -8 या एएससीआईआई में बाइट मान 65 के साथ चरित्र है, इसमें éचरित्र भी है (उदाहरण के लिए आमतौर पर फ्रेंच या स्पेनिश में उपयोग किया जाता है), लेकिन बाइट मूल्य 233 के साथ, इसमें। वर्ण नहीं है।

उस वातावरण में, wc -cऔर wc -mहमेशा एक ही परिणाम देगा।

अधिकांश आधुनिक यूनिक्स जैसी प्रणालियों पर उबंटू में, डिफ़ॉल्ट आमतौर पर यूटीएफ -8 है क्योंकि यह एकमात्र समर्थित वर्ण सेट (और एन्कोडिंग) है जो पूरे यूनिकोड रेंज को कवर करता है।

अन्य मल्टी-बाइट चरित्र एन्कोडिंग मौजूद हैं, लेकिन वे उबंटू पर समर्थित नहीं हैं और आपको उन लोगों के साथ एक स्थान उत्पन्न करने में सक्षम होने के लिए हुप्स से गुजरना पड़ता है, और यदि आप करते हैं, तो आप पाएंगे कि कई चीजें नहीं हैं ठीक से काम करो।

तो उबंटू पर प्रभाव में, चरित्र सेट या तो सिंगल-बाइट, या यूटीएफ -8 हैं।

अब, कुछ और नोट:

UTF-8 में, सभी बाइट अनुक्रम वैध वर्ण नहीं बनाते हैं। उदाहरण के लिए, सभी UTF-8 अक्षर जो ASCII वाले नहीं हैं, बाइट्स के साथ बनते हैं, जिनमें से सभी का 8 वां बिट सेट होता है, लेकिन जहां पहले वाले में 7 वां बिट सेट होता है।

यदि आपके पास 8 वें बिट सेट के साथ बाइट्स का क्रम है, जिनमें से कोई भी 7 बिट सेट नहीं है, तो उसे किसी वर्ण में अनुवादित नहीं किया जा सकता है। और ऐसा तब है जब आप समस्याओं और विसंगतियों को शुरू कर रहे हैं क्योंकि सॉफ़्टवेयर को नहीं पता है कि उन लोगों के साथ क्या करना है। उदाहरण के लिए:

$ printf '\200\200\200' | wc -mc
      0       3
$ printf '\200\200\200' | grep -q . || echo no
no

wcऔर grepवहां कोई चरित्र नहीं मिलता है लेकिन:

$ x=$'\200\200\200' bash -c 'echo "${#x}"'
3

bash पाता है 3. जब यह एक चरित्र को बाइट्स के अनुक्रम को मैप नहीं कर सकता है, तो यह प्रत्येक बाइट को एक चरित्र मानता है।

यह और भी अधिक जटिल हो सकता है क्योंकि यूनिकोड में कोडपॉइंट्स हैं जो वर्णों के रूप में अमान्य हैं, और कुछ जो गैर-वर्ण हैं , और उपकरण के आधार पर, उनके UTF-8 एन्कोडिंग को एक चरित्र के रूप में माना जा सकता है या नहीं माना जा सकता है।

एक और बात को ध्यान में रखना चरित्र और अंगूर के बीच अंतर है, और वे कैसे प्रदान किए जाते हैं।

$ printf 'e\u301\u20dd\n'
é⃝
$ printf 'e\u301\u20dd' | wc -mc
      3       6

वहाँ, हमने 3 वर्णों को 6 बाइट्स के रूप में एक वर्णमाला के रूप में प्रस्तुत किया है, क्योंकि हमें 3 वर्ण एक साथ मिल गए हैं (एक आधार वर्ण, एक तीव्र उच्चारण और एक संयोजन घेरा)।

उबुन्टु wcपर पाया गया GNU कार्यान्वयन -Lइनपुट में सबसे चौड़ी लाइन की डिस्प्ले चौड़ाई बताने के लिए एक स्विच है:

$ printf 'e\u301\u20dd\n' | wc -L
1

आपको यह भी पता चलेगा कि कुछ अक्षर उस चौड़ाई की गणना में 2 कोशिकाओं पर कब्जा कर लेते हैं जैसे कि ऊपर से हमारा चरित्र:

$ echo 乕 | wc -L
2

निष्कर्ष रूप में: जंगल शब्द में, बाइट, वर्ण और अंगूर जरूरी नहीं हैं।


1

के बीच का अंतर wc -cऔर wc -mmultibyte वर्ण (जैसे कि, UTF8), पूर्व में गिना जाता है बाइट्स के साथ एक स्थान में है कि, जबकि बाद की गिनती के अक्षर। निम्नलिखित फ़ाइल पर विचार करें:

$ hexdump -C dummy.txt 
00000000  78 79 cf 80 0a                                    |xy...|

(उन लोगों के लिए जो UTF8 नहीं बोलते हैं, वे अक्षर 'x', 'y' और 'speak' हैं, उसके बाद एक नई रूपरेखा है)। यह पाँच बाइट लंबा है:

$ wc -c dummy.txt 
5 dummy.txt

लेकिन केवल चार वर्ण लंबे:

$ wc -m dummy.txt 
4 dummy.txt

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