मैं कमांड लाइन के साथ पाठ फ़ाइल में किसी शब्द के होने की संख्या कैसे गिनूं?


43

मेरे पास एक बड़ी JSON फाइल है जो एक लाइन पर है, और मैं कमांड लाइन का उपयोग फाइल में किसी शब्द की संख्या को गिनने में सक्षम होना चाहता हूं। मैं उसे कैसे कर सकता हूँ?


यह स्पष्ट नहीं है कि शब्द JSON डेटा की कुंजी और मान दोनों में मेल खाना { "key": "the key" }चाहिए , अर्थात keyएक या दो बार स्ट्रिंग की गणना करनी चाहिए या नहीं।
Kusalananda

जवाबों:


45
$ tr ' ' '\n' < FILE | grep WORD | wc -l

जहां trनई grepलाइनों के साथ रिक्त स्थान की जगह, WORD से मेल खाते सभी परिणामी लाइनों को फ़िल्टर करता है और wcशेष लोगों को गिनता है।

एक भी grep wcके -cविकल्प का उपयोग करके भाग को बचा सकता है :

$ tr ' ' '\n' < FILE | grep -c WORD

-cविकल्प POSIX द्वारा परिभाषित किया गया है।

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

tr '"' '\n'

या

tr "'" '\n'

यदि आप डबल या सिंगल कोट्स को बदलना चाहते हैं। बेशक, आप trएक ही बार में कई पात्रों को बदलने के लिए उपयोग कर सकते हैं (विभिन्न प्रकार के व्हाट्सएप और विराम चिह्नों पर विचार करें)।

यदि आपको WORD की गिनती करने की आवश्यकता है लेकिन उपसर्ग नहीं, WORDsuffix या PrefixWORDsuffix, तो आप WORD पैटर्न को शुरू / अंत-लाइन मार्करों में संलग्न कर सकते हैं:

grep -c '^WORD$'

जो हमारे संदर्भ में शब्द-आरंभ / अंत मार्करों के बराबर है:

grep -c '\<WORD\>'

क्या होगा अगर कोई स्थान नहीं है, अर्थात क्षेत्र का नाम उद्धरण से घिरा हुआ है? उदाहरण के लिए "फ़ील्ड"
मिथक

@mythz: इसके बाद आप उद्धरणों को tr के साथ newlines से प्रतिस्थापित करते हैं। मैं जवाब अपडेट कर दूंगा।
मैक्सक्लेपजिग

1
यह जवाब कई मायनों में गलत है। यह अस्पष्ट है: आपको यह बताना चाहिए trकि ऐसे कमांड के साथ कैसे आना चाहिए जो उदाहरणों के सुझाव के बजाय काम करता है जो सभी स्थितियों में कभी काम नहीं करेगा। यह उन शब्दों से भी मेल खाएगा जिनमें वह शब्द होता है जिसे आप ढूंढ रहे हैं। grep -o '\<WORD\>' | wc -lसमाधान कहीं बेहतर है।
सैम होसेवर

1
@Sam, यह सवाल इस तरह का खुला छोड़ देता है, अगर किसी खोजे गए शब्द को 'WORD' या '\ <WORD \>' की तरह खोजना चाहिए - तो आप इसे दोनों तरीकों से पढ़ सकते हैं। यहां तक ​​कि अगर आप इसे 2 तरह से और केवल 2 तरीके से पढ़ते हैं, तो मेरा जवाब केवल 1 एक तरीके से गलत होगा। ;) और 'grep -o' समाधान केवल श्रेष्ठ है, अगर यह -o विकल्प का समर्थन करता है - जो कि POSIX द्वारा निर्दिष्ट नहीं है ... ठीक है, मुझे नहीं लगता है कि tr का उपयोग इसे कॉल करने के लिए विदेशी है अस्पष्ट ...
मैक्सक्लेपज़िग

1
@ कुसलानंद, खैर, यह अभी भी एक घटना है। लेकिन अगर आप ऐसे स्थानापन्न मिलान की गणना नहीं करना चाहते हैं, तो कृपया मेरे उत्तर के अंतिम पैराग्राफ और मेरी पिछली टिप्पणी को यहां पढ़ें।
मैक्सक्लेपज़िग

24

GNU grep के साथ, यह काम करता है: grep -o '\<WORD\>' | wc -l

-o प्रत्येक लाइन के प्रत्येक मिलान वाले भागों को एक अलग रेखा पर प्रिंट करता है।

\<एक शब्द की शुरुआत का \>संकेत देता है और एक शब्द के अंत (पर्ल के समान \b) का दावा करता है, इसलिए यह सुनिश्चित करता है कि आप एक शब्द के बीच में एक स्ट्रिंग से मेल नहीं खा रहे हैं।

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

$ अजगर -c 'यह आयात करें' | grep '\ <एक \>'
वहाँ होना चाहिए एक ही और अच्छा होगा यदि - एक यह करने के लिए जिस तरह से --obvious।
नाम स्थान एक महान विचार का सम्मान कर रहे हैं - चलो उन में से अधिक करते हैं!
$ अजगर -c 'आयात यह' | ग्रेप -ओ '\ <एक \>'
 एक 
एक 
एक 
$ अजगर -c 'इस आयात' | grep -o '\ <एक \>' | wc -l
3

1
या बसgrep -wo WORD | wc -l
स्टीफन चेज़लस

10

यह दुर्भाग्य से GNU के साथ काम नहीं करता हैcoreutils

grep -o -c WORD file

यदि यह आपके प्लेटफ़ॉर्म पर काम करता है, तो यह एक सुरुचिपूर्ण और काफी सहज समाधान है; लेकिन ग्नू लोग अभी भी सोच रहे हैं।


2
मेरा बुरा, बग अभी भी खुला है: savannah.gnu.org/bugs/?33080
tripleee

1
बहुत बुरा यह
MasterScrat

यह मेरे लिए काम किया!
इटारू जी

ये गलत है। यह पैटर्न WORD के साथ लाइनों की संख्या को गिनता है। ओपी घटनाओं की कुल संख्या चाहता है।
पियरे बी

@PierreB यही कारण है कि मैं कह रहा हूँ कि GNU grepयहाँ एक बग है। यह POSIX से स्पष्ट नहीं है कि संयोजन के शब्दार्थ क्या होना चाहिए -cऔर -oइसलिए यह वर्तमान में पोर्टेबल नहीं है। टिप्पणी के लिए धन्यवाद; मैंने इसका उत्तर अपडेट कर दिया है।
ट्रिपल

7
sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl 

यह कमांड निम्नलिखित बनाती है:

  1. रिक्त स्थान के साथ सभी गैर अल्फ़ान्यूमेरिक वर्णों को प्रतिस्थापित करें।
  2. सभी लाइन ब्रेक को रिक्त स्थान में भी परिवर्तित किया जाता है।
  3. एक रिक्त स्थान के लिए सभी कई रिक्त स्थान कम कर देता है
  4. सभी स्थान अब लाइन ब्रेक में परिवर्तित हो गए हैं। एक पंक्ति में प्रत्येक शब्द।
  5. 'हैलो' और 'हैलो' से बचने के लिए अलग-अलग शब्दों में कम करने के लिए सभी शब्दों का अनुवाद करता है
  6. संतों का पाठ
  7. गिनता है और समान रेखाओं को हटाता है
  8. सबसे लगातार शब्दों को गिनने के लिए शॉर्ट्स रिवर्स होता है
  9. प्रत्येक शब्द के लिए एक पंक्ति संख्या को जोड़ दें ताकि शब्द को पूरी तरह से पता चल सके

उदाहरण के लिए, यदि मैं पहले लिनुस टोरवाल्ड संदेश को एनालाइज़ करना चाहता हूँ:

प्रेषक: torvalds@klaava.Helsinki.FI (लीनस बेनेडिक्ट टॉर्वाल्ड्स) समाचार समूह: comp.os.minix विषय: आप मिनिक्स में सबसे अधिक क्या देखना चाहेंगे? सारांश: मेरे नए ऑपरेटिंग सिस्टम के लिए छोटा मतदान संदेश-आईडी: <1991Aug25.205708.9541@klaava.Helsinki.FI> दिनांक: 25 अगस्त 91 20:57:08 GMT संगठन: हेलसिंकी विश्वविद्यालय

नमस्कार का उपयोग करते हुए सभी को नमस्कार -

मैं ३ for६ (४ 38६) क्लोन के लिए एक नि: शुल्क (मुक्त) ऑपरेटिंग सिस्टम (बस एक शौक नहीं, विष्णु की तरह बड़ा और पेशेवर होगा) कर रहा हूं। अप्रैल के बाद से यह पक रहा है, और तैयार होना शुरू हो रहा है। मैं लोगों को / minix में नापसंद जैसी चीजों पर कोई प्रतिक्रिया चाहता हूं, क्योंकि मेरा OS इसे कुछ हद तक समान है (फाइल-सिस्टम का एक ही भौतिक लेआउट (व्यावहारिक कारणों से) अन्य चीजों के बीच)।

मैंने वर्तमान में bash (1.08) और gcc (1.40) पोर्ट किया है, और चीजें काम करने लगती हैं। इसका तात्पर्य यह है कि मुझे कुछ महीनों के भीतर कुछ व्यावहारिक मिल जाएगा, और मैं जानना चाहूंगा कि ज्यादातर लोग क्या सुविधाएँ चाहते हैं। किसी भी सुझाव का स्वागत है, लेकिन मैं वादा नहीं करता कि मैं उन्हें लागू करूंगा but

लिनुस (torvalds@kruuna.helsinki.fi)

पुनश्च। हां - यह किसी भी मिनिक्स कोड से मुक्त है, और इसमें एक बहु-थ्रेडेड fs है। यह प्रदर्शन करने योग्य नहीं है (386 कार्य स्विचिंग आदि का उपयोग करता है), और यह शायद एटी-हार्डडिस्क के अलावा किसी भी चीज का समर्थन नहीं करेगा, क्योंकि मेरे पास यह सब है :-(।

मैं linus.txt नाम की एक फाइल बनाता हूं , मैं सामग्री पेस्ट करता हूं और फिर मैं कंसोल में लिखता हूं:

sed -e 's/[^[:alpha:]]/ /g' linus.txt | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl 

बाहर रखा जाएगा:

 1        7 i
 2        5 to
 3        5 like
 4        5 it
 5        5 and
 6        4 minix
 7        4 a
 8        3 torvalds
 9        3 of
10        3 helsinki
11        3 fi
12        3 any
13        2 would
14        2 won
15        2 what
16        ...

यदि आप केवल पहले 20 शब्दों की कल्पना करना चाहते हैं:

sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl | head -n 20

यह नोट करना महत्वपूर्ण है कि कमांड tr 'AZ' 'a-z' UTF-8 को अभी तक अधिग्रहित नहीं करता है , ताकि विदेशी भाषाओं में APR theS शब्द को aprÈs के रूप में अनुवादित किया जा सके।

यदि आप केवल एक शब्द की घटना के लिए खोज करना चाहते हैं, तो आप अंत में एक grep जोड़ सकते हैं:

sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl | grep "\sword_to_search_for$"

Search_freq नामक स्क्रिप्ट में :

#!/bin/bash
sed -e 's/[^[:alpha:]]/ /g' text_to_analize.txt | tr '\n' " " |  tr -s " " | tr " " '\n'| tr 'A-Z' 'a-z' | sort | uniq -c | sort -nr | nl | grep "\s$1$"

स्क्रिप्ट को बुलाया जाना चाहिए:

 search_freq word_to_search_for

sed: -e expression #2, char 7: unterminated s 'कमांड', यह भी सभी शब्दों को गिनता है, है ना? लेकिन ओपी ने केवल एक विशेष से पूछा। इसके अलावा स्पष्टीकरण का एक सा अच्छा होगा।
phk

सॉरी मेरी एक गलती थी। मैंने कमांड को रीमेक किया है और साथ ही जवाब में टिप्पणी की है। मेरी राय में, सवाल से, यह जानना असंभव है कि वह केवल एक शब्द या परिणामों की आवृत्ति के ऑक्जेरी को प्राप्त करना चाहेगा। लेकिन यदि आप केवल एक शब्द प्राप्त करना चाहते हैं, तो आप अंत में एक grep जोड़ सकते हैं।
रोजर बोरेल

3

इस पर निर्भर करते हुए कि आप कुंजी में या JSON डेटा के मूल्यों में शब्द का मिलान करना चाहते हैं या नहीं, आप डेटा से केवल कुंजियाँ या केवल मान निकालना चाहते हैं। अन्यथा आप कुछ शब्दों को कई बार गिन सकते हैं यदि वे कुंजी और मान दोनों के रूप में होते हैं।

सभी कुंजी निकालने के लिए:

jq -r '..|objects|keys[]' <file.json

यह पुनरावर्ती परीक्षण करता है कि क्या वर्तमान वस्तु एक वस्तु है, और यदि यह है, तो यह कुंजी निकालता है। आउटपुट कुंजियों की एक सूची होगी, प्रति पंक्ति एक।

सभी मान निकालने के लिए:

jq -r '..|scalars' <file.json

यह एक समान तरीके से काम करता है, लेकिन इसके कम चरण हैं।

फिर आप उपरोक्त के माध्यम से grep -c 'PATTERN'(कुंजियों या मूल्यों के खिलाफ कुछ पैटर्न से मेल खाने के लिए), या grep -c -w -F 'WORD'( कुंजियों या मूल्यों में किसी शब्द से मेल खाने के लिए ), या grep -c -x -F 'WORD'(पूर्ण कुंजी या मूल्य से मेल खाने के लिए), या इसी तरह के पाइप को पाइप कर सकते हैं। अपनी गिनती करो।


0

मेरे पास कुछ इस तरह से है: "number":"OK","number":OK"एक पंक्ति में कई बार दोहराया।

मेरा सरल "ओके" काउंटर:

sed "s|,|\n|g" response | grep -c OK


-1

i ने आवक की संख्या ज्ञात करने के लिए awk कमांड के नीचे उपयोग किया है

उदाहरण फ़ाइल

बिल्ली file1

praveen ajay 
praveen
ajay monkey praveen
praveen boy praveen

आदेश:

awk '{print gsub("praveen",$0)}' file1 | awk 'BEGIN{sum=0}{sum=sum+$1}END{print sum}'

उत्पादन

awk '{print gsub("praveen",$0)}' file1 | awk 'BEGIN{sum=0}{sum=sum+$1}END{print sum}'

5

या बस awk '{sum+=gsub("praveen","")} END {print sum+0}'
जी-मैन का कहना है कि 'मोनिका'

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