Ich habe einen Befehl (cmd1), der eine Protokolldatei durchsucht, um eine Reihe von Zahlen herauszufiltern. Die Zahlen sind in zufälliger Reihenfolge, daher verwende ich sort -gr, um eine umgekehrt sortierte Liste von Zahlen zu erhalten. Diese sortierte Liste enthält möglicherweise Duplikate. Ich muss die Anzahl für jede eindeutige Nummer in dieser Liste finden.
Zum Beispiel, wenn die Ausgabe von cmd1 ist:
100
100
100
99
99
26
25
24
24
Ich benötige einen anderen Befehl, an den ich die obige Ausgabe weiterleiten kann, damit ich Folgendes erhalte:
100 3
99 2
26 1
25 1
24 2
bash
command-line
sorting
count
duplicates
letronje
quelle
quelle
Antworten:
wie wäre es mit;
$ 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}'
Das Ergebnis ist :
quelle
100 3 99 2 26 1 25 1 24 2 2 24
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
so erhalten Sie:100 3 99 2 26 1 25 1 24 2
uniq -c
funktioniert mindestens für GNU uniq 8.23 und macht genau das, was Sie wollen (unter der Annahme einer sortierten Eingabe).quelle
sort
Befehl hinzu:sort file_name | uniq -c
wenn die Reihenfolge nicht wichtig ist
# 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
quelle
Sortieren Sie die Zahlen numerisch in umgekehrter Reihenfolge, zählen Sie dann die Duplikate und tauschen Sie das linke und das rechte Wort aus. In Spalten ausrichten.
printf '%d\n' 100 99 26 25 100 24 100 24 99 \ | sort -nr | uniq -c | awk '{printf "%-8s%s\n", $2, $1}'
quelle
In Bash können wir ein assoziatives Array verwenden, um Instanzen jedes Eingabewerts zu zählen. Angenommen, wir haben den Befehl
$cmd1
, z#!/bin/bash cmd1='printf %d\n 100 99 26 25 100 24 100 24 99'
Dann können wir Werte in der Array-Variablen
a
mit dem++
mathematischen Operator für die relevanten Array-Einträge zählen:while read i do ((++a["$i"])) done < <($cmd1)
Wir können die resultierenden Werte drucken:
for i in "${!a[@]}" do echo "$i ${a[$i]}" done
Wenn die Reihenfolge der Ausgabe wichtig ist, benötigen wir möglicherweise eine externe
sort
Taste:for i in $(printf '%s\n' "${!a[@]}" | sort -nr) do echo "$i ${a[$i]}" done
quelle