Я пытаюсь найти способ найти и распечатать только строки из файла, которые не имеют дубликатов. Если это - мой файл:
A
A
B
B
C
C
Y
Z
Я пытаюсь распечатать только
Y
Z
К сожалению, я продолжаю добираться
A
B
C
Y
Z
Я попробовал sort -u
, sort | uniq -u
, и grep | sort | uniq -u
с теми же результатами. Я в конечном счете смог достигнуть своей цели нахождения уникального использования строки uniq -c
и поиск строки, которая только появляется одно время, но я хотел бы знать, как сделать это правильно в будущем.
$ awk '{arr[$0]++};END{for(var in arr) if (arr[var] == 1) print var}' input.txt
Y
Z
{arr[$0]++};
создает ассоциативный массив пар номера строки. Если строка будет уникальна в файле, то объект массива, который соответствует значению строки, будет 1, иначе - больше, чем 1END
блок выполняется, когда мы достигли конца файла. Мы выполняем итерации по использованию объектов массива for(value in array)
цикл и печать значение, если соответствующий объект массива равняется 1, как упомянуто прежде.Та же идея как awk
один. Здесь мы используем OrderedDict
класс для создания словаря строк и их количеств с сохраненным порядком.
#!/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)
И здесь это в действии:
$ ./get_unique_lines.py input.txt
Y
Z
Снова, та же идея как сценарий Python, и мы используем заказанный хеш (см. также Связь:: документация IxHash).
#!/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;
}
Тестовый прогон:
$ ./get_unique_lines.pl input.txt
Y
Z
Многократно уже были упомянуты в комментариях.
$ sort input.txt | uniq -u
Y
Z
или
$ uniq -u input.txt
Y
Z