Почему uniq, кажется, держит несколько последовательных идентичных строк?

Без uniq:

amin@ubuntu:~/Desktop$ cut -f 1 info.log | tail -n +2 | head -n -1 | sort
Abol
Abol 
Ahmad
Akbar
Arash
Hadi 
Hamed
Mahmood
Maryam
Maryam
Mohsen
NIma
Rasool
Sadegh
Sepide
Sepide 

С uniq:

amin@ubuntu:~/Desktop$ cut -f 1 info.log | tail -n +2 | head -n -1 | sort | uniq
Abol
Abol 
Ahmad
Akbar
Arash
Hadi 
Hamed
Mahmood
Maryam
Mohsen
NIma
Rasool
Sadegh
Sepide
Sepide 

Как вы видите, результат одинаков для обоих, почему?

1
задан 26 August 2019 в 15:54

1 ответ

TL; DR: строки имеют другой пробел (возможно пробелы) в конце.

Это происходит, когда у Вас есть строки, которые выглядят одинаково, но являются, на самом деле отличаются из-за символов, которые не отображаются в Вашем терминале, обычно в конце. Часто это, конечные пробелы (как fkraiem предложенный) или непоследовательные разделители строки.

Вы могли бы ожидать, что запуск конвейера, как Вы делаете, с cut, предотвратил бы это. Это не делает, все же. cut использует вкладку в качестве ее разделителя по умолчанию. (Читатели, которые хотят проверить это поведение - и его отношение к наличию неожиданных дублирующихся строк после uniq- может попробовать cut -f 1 <<<$'foo\nfoo ' | uniq, который печатает две строки.)

Решение в Вашем случае состоит в том, чтобы, вероятно, использовать что-то другое, чем cut -f 1 выбрать поля. В частности, если поля разделяются пробелами вместо вкладок - можно ли одиночным пробелом или несколькими пробелами, и даже если количество пробелов отличается в различных записях - затем, использовать cut -d' ' -f 1 вместо этого, указывая пространство как символ-разделитель. Или Вы не могли бы хотеть использовать cut вообще, но вместо этого используйте awk '{ print $1 }', который печатает первое поле, беря любую последовательность последовательных пробелов и вкладок как разделитель.

Вы могли альтернативно разделить запаздывающий пробел, хотя это делает Вашу команду еще более сложной. Один способ сделать, который был бы путем передачи по каналу текста через sed -E 's/[[:space:]]+$//' прежде чем это перейдет в uniq.

Как примечание стороны, если безотносительно команды Вы в конечном счете используете все еще, заканчивает тем, что передал вывод по каналу sort непосредственно к uniq, Вы могли бы рассмотреть просто использование sort -u для этого вместо этого.

2
ответ дан 7 December 2019 в 13:14

Другие вопросы по тегам:

Похожие вопросы: