कमांड लाइन टूल का उपयोग करके क्रमबद्ध अनुक्रम में डुप्लिकेट की गिनती करना


82

मेरे पास एक कमांड (cmd1) है जो संख्याओं के एक समूह को फ़िल्टर करने के लिए लॉग फ़ाइल के माध्यम से पकड़ती है। संख्याएँ यादृच्छिक क्रम में होती हैं, इसलिए मैं संख्याओं की रिवर्स सॉर्ट की गई सूची प्राप्त करने के लिए सॉर्ट -gr का उपयोग करता हूं। इस क्रमबद्ध सूची में डुप्लिकेट हो सकते हैं। मुझे उस सूची में प्रत्येक अद्वितीय संख्या के लिए गिनती खोजने की आवश्यकता है।

उदाहरण के लिए यदि cmd1 का आउटपुट है:

100 
100 
100 
99 
99 
26 
25 
24 
24

मुझे एक और कमांड की आवश्यकता है जिसे मैं उपरोक्त आउटपुट को पाइप कर सकता हूं, ताकि, मुझे मिल जाए:

100     3
99      2
26      1
25      1
24      2


जवाबों:


94

कैसा रहेगा;

$ echo "100 100 100 99 99 26 25 24 24" \
    | tr " " "\n" \
    | sort \
    | uniq -c \
    | sort -k2nr \
    | awk '{printf("%s\t%s\n",$2,$1)}END{print}'

परिणाम है :

100 3
99  2
26  1
25  1
24  2

1
मैंने इसे चलाया और इसने अंत में $ 1, $ 2 का एक अतिरिक्त प्रिंट स्टेटमेंट तैयार किया:100 3 99 2 26 1 25 1 24 2 2 24
Mittenchops

3
निम्नलिखित परिणामों के बीच एक नई रेखा जोड़ता है और अंत में अतिरिक्त रेखा को हटा देता है: echo "100 100 100 99 99 26 25 24 24" | tr " " "\n" | sort | uniq -c | sort -k2nr | awk '{printf("%s\t%s\n",$2,$1)}END{print}' | head -n -1इसलिए आपको प्राप्त होता है:100 3 99 2 26 1 25 1 24 2
वुडी

सिंटैक्स के बारे में ध्यान दें, आप बैकस्लैश का उपयोग करने के बजाय एक पाइप के साथ एक पंक्ति को समाप्त कर सकते हैं।
वेजेंड्रिया

54

uniq -c GNU uniq 8.23 ​​के लिए काम करता है कम से कम, और ठीक वैसा ही जैसा आप चाहते हैं (क्रमबद्ध इनपुट मानकर)।


2
अगर इनपुट सॉर्ट नहीं किया जाता है, तो केवल sortकमांड जोड़ें :sort file_name | uniq -c
मिखाइल गेयर

बहुत बढ़िया। मैक ओएस एक्स पर भी काम करता है! Mojave 10.14.6 पर परीक्षण किया गया।
22

10

यदि आदेश महत्वपूर्ण नहीं है

# echo "100 100 100 99 99 26 25 24 24" | awk '{for(i=1;i<=NF;i++)a[$i]++}END{for(o in a) printf "%s %s ",o,a[o]}'
26 1 100 3 99 2 24 2 25 1

3 कम पाइपों के साथ ऐसा करने के लिए +1। यह बहुत बढ़िया होगा यदि आप इस बारे में विस्तार से बता सकते हैं कि यह कैसे काम करता है b / c यह मुझे भ्रमित करता है। ;-) धन्यवाद।
सक्सैडडी

9

संख्याओं को रिवर्स में क्रमबद्ध करें, फिर डुप्लिकेट की गणना करें, फिर बाएं और दाएं शब्दों को स्वैप करें। कॉलम में संरेखित करें।

printf '%d\n' 100 99 26 25 100 24 100 24 99 \
   | sort -nr | uniq -c | awk '{printf "%-8s%s\n", $2, $1}'
100     3
99      2
26      1
25      1
24      2

2

बैश में, हम प्रत्येक इनपुट मूल्य के उदाहरणों को गिनने के लिए एक साहचर्य सरणी का उपयोग कर सकते हैं । यह मानते हुए कि हमारे पास कमांड है $cmd1, जैसे

#!/bin/bash

cmd1='printf %d\n 100 99 26 25 100 24 100 24 99'

फिर हम संबंधित सरणी प्रविष्टियों पर गणितीय ऑपरेटर aका उपयोग करके सरणी चर में मानों की गणना कर सकते ++हैं:

while read i
do
    ((++a["$i"]))
done < <($cmd1)

हम परिणामस्वरूप मूल्यों को प्रिंट कर सकते हैं:

for i in "${!a[@]}"
do
    echo "$i ${a[$i]}"
done

यदि आउटपुट का क्रम महत्वपूर्ण है, तो हमें sortकुंजी की एक बाहरी आवश्यकता हो सकती है :

for i in $(printf '%s\n' "${!a[@]}" | sort -nr)
do
    echo "$i ${a[$i]}"
done
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.