Подсчет количества уникальных значений на основе двух столбцов в bash - PullRequest
1 голос
/ 19 июня 2020

У меня есть файл с разделением табуляцией, который выглядит следующим образом:

A 1234
A 123245
A 4546
A 1234
B 24234
B 4545
C 1234
C 1234

Output: 
A 3
B 2
C 1

В основном мне нужно количество уникальных значений, которые принадлежат первому столбцу, все в одном коммандос с конвейерами. Как видите, могут быть дубликаты типа «A 1234». У меня были идеи с awk или cut, но, похоже, ни один из них не работает. Они просто распечатывают все уникальные пары, а мне нужно подсчет уникальных значений из второго столбца с учетом значения в первом.

awk -F " "'{print $1}' file.tsv | uniq -c
cut -d' ' -f1,2 file.tsv | sort | uniq -ci

Я буду очень признателен за вашу помощь! Заранее спасибо.

Ответы [ 5 ]

4 голосов
/ 19 июня 2020

С полным решением awk не могли бы вы попробовать следующее.

awk 'BEGIN{FS=OFS="\t"} !found[$0]++{val[$1]++} END{for(i in val){print i,val[i]}}' Input_file

Пояснение: Добавление подробного объяснения для выше.

awk '                  ##Starting awk program from here.
BEGIN{
  FS=OFS="\t"
}
!found[$0]++{       ##Checking condition if 1st and 2nd column is NOT present in found array then do following.
  val[$1]++            ##Creating val with 1st column inex and keep increasing its value here.
}
END{                   ##Starting END block of this progra from here.
  for(i in val){       ##Traversing through array val here.
    print i,val[i]     ##Printing i and value of val with index i here.
  }
}
'  Input_file          ##Mentioning Input_file name here.
2 голосов
/ 19 июня 2020

Использование GNU awk:

$ gawk -F\\t '{a[$1][$2]}END{for(i in a)print i,length(a[i])}' file

Вывод:

A 3
B 2
C 1

Объяснение:

 $ gawk -F\\t '{               # using GNU awk and tab as delimiter
    a[$1][$2]                  # hash to 2D array
 }
 END {                         
     for(i in a)               # for all values in first field
         print i,length(a[i])  # output value and the size of related array
 }' file
1 голос
/ 20 июня 2020

Другой способ, используя удобную GNU datama sh утилиту:

$ datamash -g1 countunique 2 < input.txt
A   3
B   2
C   1

Требует, чтобы входной файл был отсортирован по первому столбцу, как в вашем примере. Если настоящего файла нет, добавьте к параметрам -s.

1 голос
/ 19 июня 2020
$ sort -u file | cut -f1 | uniq -c
   3 A
   2 B
   1 C
1 голос
/ 19 июня 2020

Вы можете попробовать следующее:

cat file.tsv | sort | uniq | awk '{print $1}' | uniq -c | awk '{print $2 " " $1}'

Это работает для вашего примера. (Но я не уверен, работает ли это в других случаях. Дайте мне знать, если это не сработает!)

...