Mantendo as linhas repetidas um número definido de vezes [duplicado]

1

Eu tenho um arquivo com várias colunas e identifiquei linhas nas quais os valores da coluna 3 foram duplicados.

Exemplo de entrada:

A B C
1 2 APPLE
3 4 PEAR
9 3 LEMON
8 3 ORANGE
8 2 APPLE
3 4 APPLE
9 3 LEMON
8 3 PEAR

Posso contar com que frequência a palavra na coluna 3 foi repetida usando:

awk '{print $3}' [input filename] | sort | uniq -c > [output filename]

Saída:

3 APPLE
2 PEAR
2 LEMON
1 ORANGE

O que eu gostaria de fazer é manter as linhas repetidas 3 vezes:

Saída desejada:

APPLE

ou

1 2 APPLE
8 2 APPLE
3 4 APPLE

Não me importo se todas as colunas forem impressas a partir do arquivo de entrada original ou apenas do valor da terceira coluna.

Usar sort -u imprime qualquer linha que tenha aparecido pelo menos uma vez, que não é o que eu estou procurando.

    
por Bob 27.09.2017 / 12:27

4 respostas

3

Outra abordagem é examinar o arquivo duas vezes, primeiro para construir uma referência e o segundo para filtrar conforme necessário

$ awk 'NR==FNR{a[$3]++; next} a[$3]==3' ip.txt ip.txt 
1 2 APPLE
8 2 APPLE
3 4 APPLE

$ awk 'NR==FNR{a[$3]++; next} a[$3]==2' ip.txt ip.txt 
3 4 PEAR
9 3 LEMON
9 3 LEMON
8 3 PEAR

$ awk 'NR==FNR{a[$3]++; next} a[$3]<2' ip.txt ip.txt 
A B C
8 3 ORANGE
    
por 27.09.2017 / 12:50
1
Solução

awk :

- para gerar apenas entradas que ocorrem pelo menos três vezes:

awk '++a[$3]==3{ print $3 }' file
  • ++a[$3] - número consecutivamente incrementado de valores únicos do 3º campo

- para gerar apenas entradas que ocorrem exatamente 3 vezes:

awk '{++a[$3]}END{ for(i in a) if(a[i]==3) print i }' file

A saída:

APPLE
    
por 27.09.2017 / 12:33
0

Passe a saída do seu pipeline por awk '$1 == 3 { print $2 }' para obter apenas APPLE .

Como alternativa, conte com awk desde o início:

awk '{ c[$3]++; r[$3] = r[$3] ? r[$3] ORS $0 : $0 } END { for (i in c) { if (c[i] == 3) print r[i] } }' file
1 2 APPLE
8 2 APPLE
3 4 APPLE

O script awk contará, em c , quantas vezes os valores na coluna 3 ocorrerão. Cada linha de entrada é anexada a r , que é um array associativo, como c , digitado na terceira coluna.

No final, apenas as linhas cuja terceira coluna ocorre exatamente três vezes são exibidas.

    
por 27.09.2017 / 12:35
0

Bem, talvez não seja a maneira mais elegante, mas o que segue funciona. Ele estende o que você já fez analisando cada linha para filtrar aquelas que têm uma contagem de ocorrências não estritamente maior que 2 .

awk '{print $3}' yourInputFile | sort | uniq -c | while read -r line
   do 
      echo $line | [ 'awk '{print $1}'' -gt 2 ] && echo $line | awk '{print $2}'
   done

E se você quiser restringir a exibição a linhas que têm uma contagem de ocorrências estritamente igual a 3 , é ainda mais simples. Um grep pode ser usado como @wvxvw sugerido nos comentários. Você nem precisa fazer uma iteração nesse caso, mas é necessário proteger o grep para não obter valores que começam com 3, mas que são maiores, como 30:

awk '{print $3}' yourInputFile | sort | uniq -c | grep '^\s*3\s' | awk '{print $2}'

Em ambos os casos, a saída é:

APPLE
    
por 27.09.2017 / 13:11