Даже после сортировки uniq продолжает повторять некоторые значения.

Справочный файл: http://snap.stanford.edu/data/wiki-Vote.txt.gz

(Это ленточный архив, содержащий файл с именем Wiki-Vote.txt)

Первые несколько строк в файле, содержащем следующее: head -n 10 Wiki-Vote.txt

# Directed graph (each unordered pair of nodes is saved once): Wiki-Vote.txt 
# Wikipedia voting on promotion to administratorship (till January 2008). 
# Directed edge A->B means user A voted on B becoming Wikipedia administrator.
# Nodes: 7115 Edges: 103689
# FromNodeId    ToNodeId
     30          1412
     30          3352
     30          5254
     30          5543
     30          7478
     3            28

Я хочу найти количество узлов в графе (хотя оно уже указано в строке 3). Я выполнил следующую команду,

awk '!/^#/ { print $1; print $2; }' Wiki-Vote.txt | sort | uniq | wc -l

Объяснение:

  • /^#/ соответствует всем строкам, начинающимся с #. И !/^#/ соответствует тому, что не соответствует.

  • awk '!/^#/ { print $1; print $2; }' Wiki-Vote.txt печатает первый и второй столбцы всех совпадающих строк в новых строках.

  • | sort направляет вывод для их сортировки.

  • | uniq должен отображать все эти уникальные значения, но не.

  • | wc -l считает предыдущие строки, и это неправильно.

Результатом приведенной выше команды является 8491, а не 7115 (как указано в строке 3). Я не знаю, почему uniq повторяет значения. Я могу сказать, что с тех пор, как awk '!/^#/ { print $1; print $2; }' Wiki-Vote.txt | sort -i | uniq | tail вернулся,

992
993
993
994
994
995
996
998
999
999

Который содержит повторяющиеся значения. Кто-нибудь, пожалуйста, запустите код и скажите мне, что я не единственный, кто получает неправильный ответ, и, пожалуйста, помогите мне понять, почему я получаю то, что получаю.


person SigSegV    schedule 13.01.2020    source источник
comment
Очень хорошо, что вы показали свои усилия в своем вопросе. Не могли бы вы опубликовать образец ввода и ожидаемый образец вывода в своем вопросе и сообщить нам об этом.   -  person RavinderSingh13    schedule 13.01.2020
comment
Окончания строк Dos   -  person KamilCuk    schedule 13.01.2020
comment
Рассмотрите возможность использования dos2unix для устранения проблем с необработанными данными и посмотрите, работает ли теперь ваш сценарий должным образом.   -  person Bee Kay    schedule 13.01.2020


Ответы (1)


Файл имеет окончание строки dos - каждая строка заканчивается символом \r CR.

Вы можете проверить свой вывод tail, например, с помощью hexdump -C, строки, начинающиеся с #, добавленные мной:

$ awk '!/^#/ { print $1; print $2; }' ./wiki-Vote.txt | sort | uniq | tail | hexdump -C
00000000  39 39 32 0a 39 39 33 0a  39 39 33 0d 0a 39 39 34  |992.993.993..994|
#                                           ^^ HERE
00000010  0a 39 39 34 0d 0a 39 39  35 0d 0a 39 39 36 0a 39  |.994..995..996.9|
#                     ^^              ^^ 
00000020  39 38 0a 39 39 39 0a 39  39 39 0d 0a              |98.999.999..|
#                                        ^^
0000002c

Поскольку uniq видит уникальные строки, одну с CR и одну без нее, они не удаляются. Удалите символ CR перед передачей. Обратите внимание, что sort | uniq лучше sort -u.

$ awk '!/^#/ { print $1; print $2; }' ./wiki-Vote.txt | tr -d '\r' | sort -u | wc -l
7115
person KamilCuk    schedule 13.01.2020