Como encontro uma única linha única em um arquivo?

0

Estou tentando encontrar uma maneira de localizar e imprimir somente linhas de um arquivo que não tenha duplicatas. Se este é o meu arquivo:

A
A
B
B
C
C
Y
Z

Estou tentando imprimir apenas

Y
Z

Infelizmente, continuo recebendo

A
B
C
Y
Z

Eu tentei sort -u , sort | uniq -u e grep | sort | uniq -u com os mesmos resultados. Finalmente, consegui atingir minha meta de encontrar a linha exclusiva usando uniq -c e procurando a linha que aparece apenas uma vez, mas gostaria de saber como fazer isso corretamente no futuro.

    
por Christian Shipley 16.05.2017 / 05:21

2 respostas

2

solução AWK

$ awk '{arr[$0]++};END{for(var in arr) if (arr[var] == 1) print var}' input.txt                                          
Y
Z
  • {arr[$0]++}; cria uma matriz associativa de pares de números de linhas. Se uma linha é única no arquivo, o item da matriz que corresponde ao valor da linha será 1, caso contrário - maior que 1
  • END block é executado quando chegamos ao final do arquivo. Nós iteramos os itens da matriz usando for(value in array) loop e imprimimos o valor se o item da matriz correspondente for igual a 1, como mencionado anteriormente.

Python 3

Mesma ideia que o awk one. Aqui usamos OrderedDict class para criar um dicionário de linhas e suas contagens com ordem preservada.

#!/usr/bin/env python3
import sys
from collections import OrderedDict

if len(sys.argv) != 2:
   sys.stderr.write(">>> Script requires a file argument")
   sys.exit(1)

for arg in sys.argv[1:]:
    lines = OrderedDict()
    with open(sys.argv[1]) as fd:
        for line in fd:
            tmp = line.strip()
            if tmp in lines.keys():
                lines[tmp] = lines[tmp] + 1
            else:
                lines[tmp] = 1

    for line,count in lines.items():
        if count == 1:
            print(line)

E aqui está em ação:

$ ./get_unique_lines.py  input.txt                                                                                       
Y
Z

Perl

Mais uma vez, a mesma ideia do script Python e estamos usando o hash ordenado (veja também the Tie :: IxHash documentation ).

#!/usr/bin/perl
use strict;
use warnings;
use Tie::IxHash;

tie my %linehash, "Tie::IxHash" or die $!;

open(my $fp,'<',$ARGV[0])  or die $!;
while(my $line = <$fp> ){
    chomp $line;
    $linehash{$line}++;
}
close($fp);

for my $key (keys %linehash) {
    printf("%s\n",$key) unless $linehash{$key} > 1;
}

Execução de teste:

$ ./get_unique_lines.pl input.txt                                                                                        
Y
Z

sort e variações do uniq

Já foram mencionados nos comentários várias vezes.

$ sort input.txt | uniq -u                                                                                               
Y
Z

ou

$ uniq -u input.txt                                                                                                      
Y
Z
    
por Sergiy Kolodyazhnyy 16.05.2017 / 06:03
0

Por favor, dê uma olhada em esta postagem no Stack Overflow

A resposta é

uniq -u test.txt
    
por user3051574 16.05.2017 / 06:28