Identificando campos duplicados e REMOVE ambos com awk

0

Anteriormente, fiz a pergunta: Identificando campos duplicados e imprima ambos com awk .

Eu tenho um arquivo com várias colunas e queria identificar as linhas em que os valores de coluna específicos (cols 3-6) foram duplicados.

Uma resposta para isso foi awk 'n=x[$3,$4,$5,$6]{print n"\n"$0;} {x[$3,$4,$5,$6]=$0;}' file

Agora tenho o problema que desejo remover TODAS as linhas identificadas usando o código acima do arquivo de dados, deixando apenas as linhas que nunca foram duplicadas.

Eu tentei usar != em vez de = , mas isso dá o mesmo resultado que = ou retorna 0 linhas. Eu também tentei: awk '!seen[$3, $4, $5, $6]++' file mas isso também mantém a primeira instância da duplicata que eu quero remover.

    
por Bob 18.01.2016 / 00:47

1 resposta

2

Embora você esteja procurando uma solução de awk , se o resultado pretendido é a eliminação de suas duplicatas e não necessariamente via awk sozinho, tente:

  1. Primeiramente, verifique se o arquivo de entrada original está classificado, por exemplo sort unsorted_file > file
  2. Execute o comando awk que você encontrou anteriormente para identificar duplicatas nas colunas 3-6 e salvar a saída em um arquivo, por exemplo file_3-6_dupes , em seu prompt de comando:
$ awk 'n=x[$3,$4,$5,$6]{print n"\n"$0;} {x[$3,$4,$5,$6]=$0;}' file > file_3-6_dupes
  1. Por fim, use comm para eliminar duplicatas, salvando a saída em um arquivo, por exemplo, file_3-6_uniques :
$ comm -23 file file_3-6_dupes > file_3-6_uniques

Como isso funciona

  • uma entrada classificada file é necessária porque comm só funciona corretamente com entradas classificadas
  • o comando awk não alterará a ordem de aparição das duplicatas que ele descobre, ele apenas segue a ordem em que estavam no file original, então, na verdade, é apenas o original file que precisa ser classificado em primeiro lugar
  • por padrão comm exibe três colunas: linhas apenas no arquivo 1, linhas somente no arquivo 2 e linhas em comum
  • arquivo 1: file
  • arquivo 2: file_3-6_dupes
  • A opção -number especifica quais das colunas de saída de comm devem ser suprimidas,
  • então -3 significa, suprima a coluna de saída 3 do comm , o que é comum.
  • file_3-6_dupes , que contém apenas duplicatas, foi derivado de file , portanto, essas duplicatas são as únicas coisas que são encontradas em comum em file e file_3-6_dupes
  • já que queremos o oposto disso, nós apenas -3 para suprimir o que é comum, quais são as duplicatas
  • em uma nota secundária, não precisamos de um -2 adicional para suprimir as coisas que estão apenas no arquivo 2, não há nenhuma, no nosso caso

Portanto, combinando o uso de awk , o arquivo original e comm , podemos atingir sua meta de eliminar linhas com duplicatas da coluna 3-6.

Dicas

  • se o file original veio do Windows, os términos de linha não-Unix poderão impedir que comm funcione corretamente com o file_3-6_dupes gerado pelo awk, para que você possa executar dos2unix on file se encontrar comm não está funcionando e tente novamente as etapas, então deve funcionar
por 18.01.2016 / 04:02