Como obter linhas de colunas exclusivas?

1

Eu tenho um único arquivo ascii (Report.dat) com estas linhas:

a  ./L1/file2.txt
c  ./L1/file1.txt
b  ./L2/file1.txt
a  ./L2/file2.txt

e preciso obter apenas as linhas em que a primeira coluna é única, da seguinte forma:

c  ./L1/file1.txt
b  ./L2/file1.txt

Como posso fazer isso usando os comandos AWK, sort ou uniq?

    
por LeMike 08.03.2018 / 12:21

1 resposta

1

Assim você obtém os "rótulos" exclusivos:

$ awk '{ print $1 }' Report.dat | sort | uniq -u
b
c

Eles podem ser convertidos em expressões regulares que correspondem ao início da linha adicionando ^ na frente das strings:

$ awk '{ print $1 }' Report.dat | sort | uniq -u | sed 's/^/^/'
^b
^c

Você pode aplicar essas expressões regulares ao arquivo original para obter as linhas correspondentes:

$ awk '{ print $1 }' Report.dat | sort | uniq -u | sed 's/^/^/' | grep -f /dev/stdin Report.dat
c  ./L1/file1.txt
b  ./L2/file1.txt

Com grep -f /dev/stdin , informamos grep para obter as expressões regulares provenientes de sed e usá-las para fazer correspondência em Report.dat .

Alternativamente, para ignorar a etapa sed :

awk '{ print "^" $1 }' Report.dat | sort | uniq -u | grep -f /dev/stdin Report.dat

Como alternativa, faça tudo em awk :

awk 'NR == FNR { c[$1]++; next } c[$1] == 1' Report.dat Report.dat

Isso lê o arquivo duas vezes. Na primeira vez, simplesmente conta o número de vezes que cada "rótulo" ocorre. Na segunda vez, ele testa o rótulo na linha atual para ver se a contagem é uma antes de imprimir a linha.

Observe que não há como analisar o arquivo duas vezes. Pode-se armazenar o arquivo completo na memória e analisá-lo duas vezes, mas isso é complicado e será problemático no caso geral quando não sabemos como os arquivos grandes são alimentados no script.

    
por 08.03.2018 / 12:33

Tags