Mam polecenie (cmd1), które przegląda plik dziennika, aby odfiltrować zestaw liczb. Liczby są w kolejności losowej, więc używam sort -gr, aby uzyskać odwrotnie posortowaną listę liczb. Na tej posortowanej liście mogą znajdować się duplikaty. Muszę znaleźć liczbę dla każdej unikalnej liczby na tej liście.
Na przykład, jeśli wyjście cmd1 to:
100
100
100
99
99
26
25
24
24
Potrzebuję innego polecenia, do którego mogę przesłać powyższe dane wyjściowe, aby uzyskać:
100 3
99 2
26 1
25 1
24 2
bash
command-line
sorting
count
duplicates
letronje
źródło
źródło
Odpowiedzi:
Co powiesz na;
$ 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}'
Wynik to :
źródło
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
więc otrzymujesz:100 3 99 2 26 1 25 1 24 2
uniq -c
działa przynajmniej dla GNU uniq 8.23 i robi dokładnie to, co chcesz (zakładając posortowane dane wejściowe).źródło
sort
polecenie:sort file_name | uniq -c
jeśli porządek nie jest ważny
# 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
źródło
Liczbowo posortuj liczby w odwrotnej kolejności, policz duplikaty, a następnie zamień lewe i prawe słowa. Wyrównaj do kolumn.
printf '%d\n' 100 99 26 25 100 24 100 24 99 \ | sort -nr | uniq -c | awk '{printf "%-8s%s\n", $2, $1}'
źródło
W Bash możemy użyć tablicy asocjacyjnej, aby policzyć wystąpienia każdej wartości wejściowej. Zakładając, że posiadamy polecenie
$cmd1
np#!/bin/bash cmd1='printf %d\n 100 99 26 25 100 24 100 24 99'
Następnie możemy policzyć wartości w zmiennej tablicowej
a
za pomocą++
operatora matematycznego na odpowiednich wpisach tablicy:while read i do ((++a["$i"])) done < <($cmd1)
Otrzymane wartości możemy wydrukować:
for i in "${!a[@]}" do echo "$i ${a[$i]}" done
Jeśli kolejność danych wyjściowych jest ważna, możemy potrzebować zewnętrznego
sort
z kluczy:for i in $(printf '%s\n' "${!a[@]}" | sort -nr) do echo "$i ${a[$i]}" done
źródło