बैश में एक कॉलम में अद्वितीय मूल्यों की गिनती प्राप्त करना


95

मेरे पास कई कॉलम वाली टैब सीमांकित फाइलें हैं। मैं एक फ़ोल्डर में सभी फ़ाइलों के लिए एक कॉलम में विभिन्न मानों की घटना की आवृत्ति को गिनना चाहता हूं और उन्हें गिनती के घटते क्रम में क्रमबद्ध करता हूं (उच्चतम गिनती पहले)। मैं लिनक्स कमांड लाइन वातावरण में इसे कैसे पूरा करूंगा?

यह किसी भी सामान्य कमांड लाइन भाषा का उपयोग कर सकता है जैसे कि awk, perl, python आदि।

जवाबों:



68

यहाँ इसे शेल में करने का एक तरीका है:

FIELD=2
cut -f $FIELD * | sort| uniq -c |sort -nr

यह इस तरह की बात है जो बहुत ही अच्छी है।


22
बात की "तरह" ... ar ar ar! :)
जॉन रिक्स

3
किंदा छँट्टी अनोखी बात। : P (btw। -d,अल्पविराम या किसी अन्य सीमांकक द्वारा फ़ील्ड का परिसीमन करने के लिए उपयोग करें )।
cprn

4
मैंने इस्तेमाल किया cut -f 1 -d ' '। आपका बहुत बहुत धन्यवाद। :)
अल्फांसो निशिकोवा

8

जीएनयू साइट यह अच्छा awk स्क्रिप्ट, जो दोनों शब्द और उनकी आवृत्ति प्रिंट पता चलता है।

संभावित परिवर्तन:

  • आप अवरोही क्रम में परिणाम देखने के लिए sort -nr(और रिवर्स wordऔर freq[word]) पाइप कर सकते हैं।
  • यदि आप एक विशिष्ट कॉलम चाहते हैं, तो आप लूप के लिए छोड़ सकते हैं और बस लिख सकते हैं freq[3]++- कॉलम नंबर के साथ 3 बदलें।

यहाँ जाता हैं:

 # wordfreq.awk --- print list of word frequencies

 {
     $0 = tolower($0)    # remove case distinctions
     # remove punctuation
     gsub(/[^[:alnum:]_[:blank:]]/, "", $0)
     for (i = 1; i <= NF; i++)
         freq[$i]++
 }

 END {
     for (word in freq)
         printf "%s\t%d\n", word, freq[word]
 }

2
महान उदाहरण स्क्रिप्ट। यह जाग की क्षमता का इतना प्रदर्शन करता है।
डेविड मान

यह स्क्रिप्ट मेरे लिए यह निर्धारित करने में मददगार थी कि एक्सेल वर्कबुक में कौन सी पंक्तियों पर मुझे वाकई ध्यान देने की जरूरत है :) (टेक्स्ट फाइल में एक्सेल कंटेंट कॉपी किया, awk और, वॉइला का उपयोग किया!, मैं grep -n के लिए एक पैटर्न फाइल बना सकता हूं) ।
बुलबुले

6

पर्ल

यह कोड सभी स्तंभों की घटनाओं की गणना करता है , और उनमें से प्रत्येक के लिए एक सॉर्ट की गई रिपोर्ट प्रिंट करता है:

# columnvalues.pl
while (<>) {
    @Fields = split /\s+/;
    for $i ( 0 .. $#Fields ) {
        $result[$i]{$Fields[$i]}++
    };
}
for $j ( 0 .. $#result ) {
    print "column $j:\n";
    @values = keys %{$result[$j]};
    @sorted = sort { $result[$j]{$b} <=> $result[$j]{$a}  ||  $a cmp $b } @values;
    for $k ( @sorted ) {
        print " $k $result[$j]{$k}\n"
    }
}

स्तंभ के रूप में पाठ को सहेजें।
इसे इस रूप में चलाएँ: perl columnvalues.pl files*

व्याख्या

लूप करते समय शीर्ष स्तर में:
* संयुक्त इनपुट फ़ाइलों की प्रत्येक पंक्ति पर लूप करें
* लाइन को @ फ़ील्ड्स सरणी में विभाजित करें
* प्रत्येक स्तंभ के लिए, परिणाम सरणी-हैश डेटा संरचना बढ़ाएँ।

लूप के लिए शीर्ष-स्तर में:
* परिणाम सरणी पर लूप
करें * कॉलम नंबर प्रिंट करें
* उस कॉलम में उपयोग किए गए मान प्राप्त
करें * मूल्यों की संख्या के
आधार पर मानों को छाँटें * मूल्य के आधार पर माध्यमिक प्रकार (उदाहरण के लिए बनाम बनाम जी बनाम। m बनाम z)
* क्रमबद्ध सूची का उपयोग करते हुए, परिणाम हैश के माध्यम से Iterate
* प्रत्येक घटना के मूल्य और संख्या को प्रिंट करें

@ डेनिस द्वारा प्रदान की गई नमूना इनपुट फ़ाइलों के आधार पर परिणाम

column 0:
 a 3
 z 3
 t 1
 v 1
 w 1
column 1:
 d 3
 r 2
 b 1
 g 1
 m 1
 z 1
column 2:
 c 4
 a 3
 e 2

.csv इनपुट

यदि आपकी इनपुट फाइलें .csv हैं, तो बदल /\s+/दें/,/

कहानियो

एक बदसूरत प्रतियोगिता में, पर्ल विशेष रूप से अच्छी तरह से सुसज्जित है।
यह एक-लाइनर ऐसा ही करता है:

perl -lane 'for $i (0..$#F){$g[$i]{$F[$i]}++};END{for $j (0..$#g){print "$j:";for $k (sort{$g[$j]{$b}<=>$g[$j]{$a}||$a cmp $b} keys %{$g[$j]}){print " $k $g[$j]{$k}"}}}' files*

2

रूबी (1.9+)

#!/usr/bin/env ruby
Dir["*"].each do |file|
    h=Hash.new(0)
    open(file).each do |row|
        row.chomp.split("\t").each do |w|
            h[ w ] += 1
        end
    end
    h.sort{|a,b| b[1]<=>a[1] }.each{|x,y| print "#{x}:#{y}\n" }
end

5
यह बहुत दिलचस्प है, क्योंकि मैंने इसका इस्तेमाल किया और यह काम किया, और इसलिए भी कि मैं इस बात से हैरान हूं कि कितना बदसूरत रूबी है .. मुझे लगा कि पर्ल बुरा था!
ryansstack

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