Eu tenho um arquivo com um identificador e um valor:
ABC123 111111
ABC123 111111
ABCDEF 333333
ABCDEF 111111
CCCCCC 333333
ABC123 222222
DEF123 444444
DEF123 444444
Ambas as colunas contêm valores duplicados, mas preciso contar linhas que tenham o mesmo ID (primeira coluna) e um valor exclusivo (segunda coluna). Isso tornaria a saída da entrada acima:
ABCDEF 2
ABC123 2
DEF123 1
CCCCCC 1
...onde a primeira coluna é o ID e a segunda coluna é a contagem de valores exclusivos na segunda coluna. Em outras palavras, preciso descobrir quantos valores únicos existem para um determinado ID .
O mais próximo que cheguei foi isso, mas tudo o que faz é contar os valores exclusivos da primeira coluna:
cut -d " " -f1 "file.txt" | uniq -cd | sort -nr | head
Como eu faria algo assim no Bash?
Isso
awk
deve funcionar para você:Isso está perto o suficiente?
Você pode filtrá-lo ainda mais com a
| grep -vw '1'
para imitar aHAVING COUNT(DISTINCT value) > 1
semântica e eliminar as duas últimas linhas da saída neste exemplo (assumindo que esse não1
é um valor legal para um identificador!).E é claro que você pode inverter a ordem das colunas de várias maneiras. Por exemplo
Com qualquer awk:
ou se o espaço em branco entre os campos puder variar, ainda usando qualquer awk:
ou com GNU awk (para matrizes multidimensionais):
Suposições:
Outra
awk
abordagem:Isso gera:
Se a saída precisar ser ordenada, canalize os resultados para o
sort
comando apropriado, por exemplo:Aqui está um Ruby para fazer isso:
Impressões:
Não está claro se
CCCCCC 1
deveria estar na saída. Nesse caso, não há necessidade de filtrar:Impressões:
Você também pode fazer este canal POSIX:
Ou use
awk
apenas para eliminar a necessidade de uniqifing comsort -u
:Qualquer uma dessas impressões (talvez em ordem diferente):
Eu aproveitaria o GNU
AWK
para esta tarefa da seguinte maneira, deixefile.txt
o conteúdo serentão
dá saída
Explicação: Eu uso um array 2D
arr
, mas sem armazenar nenhum valor (apenas chaves), então itero sobre a alavanca superior e para cada um detectei o número de subchaves usandolength
a função. Se você precisar de uma certa ordem na saída definidaPROCINFO["sorted_in"]
comoBEGIN
uma ordem de digitalização de matriz predefinida, por exemplodará saída
ou seja, ordem lexicográfica ascendente
(testado em GNU Awk 5.1.0)
Com
bash
o uso de array associativo que (na minha opinião) é uma versão pobre daawk
abordagem de mark markp-fuso.• Será muito, muito lento em dados/arquivos grandes.
• Consulte Problema com contexto aritmético de matriz associativa