Como remover linhas duplicadas com o awk, mantendo linhas vazias?


13

O awkcomando abaixo remove todas as linhas duplicadas, conforme explicado aqui :

awk '!seen[$0]++'

Se o texto contiver linhas vazias, todas, exceto uma linha vazia, serão excluídas.

Como posso manter todas as linhas vazias enquanto excluo todas as linhas duplicadas não vazias, usando apenas awk? Por favor, inclua também uma breve explicação.

Respostas:


28

Outra opção é verificar NF, por exemplo:

awk '!NF || !seen[$0]++'

11

alternativamente

awk '!/./ || !seen[$0]++' file

O truque principal é o mesmo, seen[$0]++cria uma entrada na seenmatriz associativa cuja chave é a linha atual ( $0). Portanto, !seen[$0]++será falso se essa linha já tiver sido vista. Ele /./está verificando se a linha contém caracteres não em branco, portanto, !/./corresponde a linhas não em branco. Combinado com || !seen[$0]++ele, todas as linhas duplicadas, exceto as em branco, ignoram e imprimem o restante.


Eu acho que essa deveria ter sido a resposta aceita. +1 para explicação!
SS Anne

5
awk '/^[[:blank:]]*$/ { print; next; }; !seen[$0]++'

Tudo o que você precisa fazer é procurar uma linha vazia (realmente vazia ou apenas em branco) primeiro.


5

Aqui está outra awksolução, semelhante à resposta de @ Thor, menos concisa, mas mais eficiente:

awk '!NF {print;next}; !($0 in a) {a[$0];print}' file

Com isso, apenas verificamos a[$0]se existe ou não. Caso contrário, inicialize-o e imprima. Nesse caso, não temos nenhuma referência, atribuição, a[$0]se ela existia.


Não medi nenhuma diferença de tempo significativa com meu arquivo de teste de 288 linhas. No entanto, seu código certamente recebe o prêmio por ser o mais legível.
Serge Stroobandt
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.