підрахунок дублікатів у відсортованій послідовності за допомогою інструментів командного рядка


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
Вуді

Зверніть увагу на синтаксис, замість того, щоб використовувати зворотну косу риску, ви можете закінчити рядок конвеєром.
wjandrea

54

uniq -c працює принаймні для GNU uniq 8.23 ​​і робить саме те, що ви хочете (за умови сортування вводу).


2
у випадку, якщо введення не відсортовано, просто додайте sortкоманду:sort file_name | uniq -c
Михайло Гейєр

Приголомшливо Працює і на Mac OS X! Тестується на Mojave 10.14.6.
bappak

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

+1 за те, що це робиться на 3 труби менше. Було б чудово, якби ви могли б детальніше розповісти, як це працює, б / к, це мене збентежило. ;-) Дякую.
SaxDaddy

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

У Bash ми можемо використовувати асоціативний масив для підрахунку екземплярів кожного вхідного значення. Припускаючи, що ми маємо команду $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 та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.