2012-05-19 12 views
6

मेरे पास एक फ़ाइल है, list.txt जिसमें शब्दों की एक सूची है। मैं यह जांचना चाहता हूं कि प्रत्येक शब्द दूसरी फ़ाइल में कितनी बार प्रकट होता है, file1.txt, फिर परिणाम आउटपुट करें। संख्या पर्याप्त के सभी का एक सरल उत्पादन, के रूप में मैं मैन्युअल रूप से एक स्प्रेडशीट प्रोग्राम के साथ list.txt में जोड़ सकते हैं, लेकिन अगर स्क्रिप्ट list.txt में प्रत्येक पंक्ति के अंत में नंबर कहते हैं, कि और भी बेहतर है, जैसे:गणना करें कि फ़ाइल में शब्द सूची से प्रत्येक शब्द कितनी बार प्रकट होता है?

bear 3 
fish 15 

मैं इस की कोशिश की है, लेकिन यह काम नहीं करता है:

cat list.txt | grep -c file1.txt 
+1

आप इनपुट फ़ाइल प्रारूप का उल्लेख करना भूल गए हैं। प्रति पंक्ति एक शब्द? क्या "शब्दों" में खाली रिक्त स्थान हो सकते हैं? डेटा सेट के बारे में क्या है जिसमें grep करने के लिए? – 0xC0000022L

+0

'list.txt1' प्रति पंक्ति एक शब्द है। एक शब्द में कुछ रिक्त स्थान हो सकते हैं। 'File1.txt' में डेटा कई वाक्यों में है, लेकिन एक लाइन कई लाइनों में कभी नहीं टूटती है। – Village

उत्तर

8

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

while read; do 
    echo -n "$REPLY " 
    fgrep -ow "$REPLY" data.txt | wc -l 
done < <(sort -u word_list.txt) 

"गुप्त सॉस" के होते हैं:

  1. निहित उत्तर चर का उपयोग कर;
  2. शब्द प्रतिस्थापन फ़ाइल से शब्द एकत्र करने के लिए प्रक्रिया प्रतिस्थापन का उपयोग कर; और
  3. यह सुनिश्चित करना कि आप डेटा फ़ाइल में पूरे शब्दों के लिए grepping कर रहे हैं।
+3

यह मिलान की रेखाओं की संख्या की गणना करेगा, न कि वास्तविक घटना गणना (यदि लाइन पर एकाधिक मिलान हैं, तो यह केवल एक के रूप में गिना जाएगा)। सिद्धांत रूप में, 'fgrep -o -c' को इसे ठीक करना चाहिए, लेकिन यह जीएनयू' कोरुटिल्स 'के कुछ हाल के संस्करणों में सही ढंग से काम नहीं करता है। – tripleee

+1

ग्रेट कैच, @ ट्रिपली। वह एक बढ़िया मामला था जिसे मैंने नहीं माना था। मैंने आपके उपयोग के मामले को संबोधित करने के लिए उत्तर अपडेट किया है। –

3

यह आपके लिए (जीएनयू sed) काम कर सकते हैं:

tr -s ' ' '\n' file1.txt | 
sort | 
uniq -c | 
sed -e '1i\s|.*|& 0|' -e 's/\s*\(\S*\)\s\(\S*\)\s*/s|\\<\2\\>.*|\2 \1|/' | 
sed -f - list.txt 

स्पष्टीकरण:

  • स्प्लिट file1.txt शब्दों में
  • क्रमबद्ध शब्द
  • गणना शब्द
  • चटाई के लिए sed स्क्रिप्ट बनाएं ch शब्द (शुरू में प्रत्येक शब्द को शून्य)
  • भागो list.txt
4

के खिलाफ ऊपर स्क्रिप्ट इस awk विधि केवल एक बार प्रत्येक फ़ाइल के माध्यम से पारित करने के लिए:

awk ' 
    # read the words in list.txt 
    NR == FNR {count[$1]=0; next} 
    # process file1.txt 
    { 
    for (i=0; i<=NF; i++) 
     if ($i in count) 
     count[$i]++ 
    } 
    # output the results 
    END { 
    for (word in count) 
     print word, count[word] 
    } 
' list.txt file1.txt 
+0

+1 सॉर्टिंग के लिए +1, इनपुट के माध्यम से एक एकल पास, कोई अस्थायी फ़ाइल नहीं। यदि आप आउटपुट में 'list.txt' से ऑर्डर को सुरक्षित रखना चाहते हैं, तो' एनआर == एफएनआर 'मामले में दूसरी सरणी में एक इंडेक्स जोड़ना आसान है। – tripleee

1

एकल लाइन आदेश

cat file1.txt |tr " " "\n"|sort|uniq -c |sort -n -r -k 1 |grep -w -f list.txt 

कमांड का अंतिम भाग grep को सूची (-f विकल्प) से मिलान करने के लिए शब्दों को पढ़ने के लिए कहता है और फिर पूरे शब्दों से मेल खाता है (-w) यानी list.txt c ऑनटेन में कार शामिल है, grep को गाड़ी को अनदेखा करना चाहिए।

हालांकि ध्यान रखें कि पूरे शब्द और grep के दृश्य का आपका दृष्टिकोण भिन्न हो सकता है। उदाहरण के लिए। हालांकि कार गाड़ी से मेल नहीं खाती है, यह कार धोने से मेल खाती है, ध्यान दें कि शब्द सीमा के लिए "-" माना जाएगा। grep शब्द सीमा के रूप में अक्षरों, संख्याओं और अंडरस्कोर को छोड़कर कुछ भी लेता है। जो कोई समस्या नहीं होनी चाहिए क्योंकि यह अंग्रेजी भाषा में किसी शब्द की स्वीकृत परिभाषा के अनुरूप है।

संबंधित मुद्दे