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 usandofor(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