Почему мой отсортированный файл больше?

28

У меня есть 2958616 байт текстовый файл. При запуске sort < file.txt | uniq > sorted-file.txtя получаю текстовый файл размером 3213965 байт. Почему мой отсортированный текстовый файл больше?

Вы можете скачать текстовые файлы здесь .

wb9688
источник
5
Ваш выходной файл имеет \r\nокончания строк, тогда как входной файл имеет \nокончания строк. Возможно, вы должны установить свой язык по-другому. Попробуйте LC_ALL=Cперед каждой командой.
meuh
2
@Meuh Вот и все! Не могли бы вы добавить это в качестве ответа?
wb9688
5
Погоди, локаль влияет на это? Какую локаль вы используете? Какой выход locale? Вы уверены, что не создали файл в какой-либо другой системе?
тердон
6
sed '/^[a-z]*$/d' < file.txt | wc -l дал мне 305 строк.
meuh
5
Ваш файл также содержит â ê î ñ ô ö öö ûте, которые не входят в набор ASCII.
тердон

Ответы:

42

В то время как ваш исходный файл имеет строки, которые заканчиваются \n, ваш отсортированный файл имеет \r\n. Дополнение - \rэто то, что меняет размер.

Чтобы проиллюстрировать это, вот что происходит, когда я запускаю вашу команду в моей системе Linux:

$ sort < file.txt | uniq > sorted-file.linux.txt
$ ls -l file.txt sorted-file.linux.txt 
-rw-r--r-- 1 terdon terdon 2958616 Jul 10 12:11 file.txt
-rw-r--r-- 1 terdon terdon 2942389 Jul 10 15:15 sorted-file.linux.txt
$ wc -l file.txt sorted-file.linux.txt 
273882 file.txt
271576 sorted-file.linux.txt

Как вы можете видеть, отсортированный дедуплицированный файл на несколько строк короче и, следовательно, на несколько байтов меньше. Ваш файл, однако, отличается:

$ wc -l sorted-file.linux.txt sorted-file.txt 
271576 sorted-file.linux.txt
271576 sorted-file.txt

Два файла имеют одинаковое количество строк, но:

$ ls -l file.txt sorted-file.linux.txt sorted-file.txt 
-rw-r--r-- 1 terdon terdon 2958616 Jul 10 12:11 file.txt
-rw-r--r-- 1 terdon terdon 2942389 Jul 10 15:15 sorted-file.linux.txt
-rw-r--r-- 1 terdon terdon 3213965 Jul 10 12:11 sorted-file.txt

Тот sorted-file.txt, который я скачал по вашей ссылке, больше. Если мы теперь рассмотрим первую строку, мы можем увидеть дополнительную \r:

$ head -n1 sorted-file.txt | od -c
0000000   a  \r  \n
0000003

Которые отсутствуют в том, что я создал в Linux:

$ head -n1 sorted-file.linux.txt | od -c
0000000   a  \n
0000002

Если мы сейчас удалим \rиз вашего файла:

$ tr -d '\r' < sorted-file.txt > new-sorted-file.txt

Мы получаем ожидаемый результат, файл, который меньше исходного, точно так же, как тот, который я создал в моей системе:

$ ls -l sorted-file.linux.txt new-sorted-file.txt file.txt
-rw-r--r-- 1 terdon terdon 2958616 Jul 10 12:11 file.txt
-rw-r--r-- 1 terdon terdon 2942389 Jul 10 15:19 new-sorted-file.txt
-rw-r--r-- 1 terdon terdon 2942389 Jul 10 15:15 sorted-file.linux.txt
terdon
источник
3
Почему команда сортировки добавила \ r в полученный файл? Разве комбинация Windows не является чем-то вроде?
Тулин Кордова
3
@ TulainsCórdova это очень хороший вопрос. Не имею представления. Я предполагаю, что OP сделал это в не родной среде, но я не знаю. И да, \r\nокончания строк - это вещь для Windows.
тердон
25

hexdump показывает это!

$ hexdump -cn 32 file.txt 
0000000   a   d   h   d  \n   a   d   s   l  \n   a   m   v   b  \n   a
0000010   o   v  \n   a   o   w  \n   a   r   o   b  \n   a   s   f   a
0000020

$ hexdump -cn 32 my-sorted.txt 
0000000   a  \n   a   a  \n   a   a   a  \n   a   a   d  \n   a   a   d
0000010   s  \n   a   a   f   j   e  \n   a   a   f   j   e   s  \n   a
0000020 

$ hexdump -cn 32 sorted-file.txt 
0000000   a  \r  \n   a   a  \r  \n   a   a   a  \r  \n   a   a   d  \r
0000010  \n   a   a   d   s  \r  \n   a   a   f   j   e  \r  \n   a   a
0000020   

Ваш отсортированный файл больше, потому что он использует окончания строки Windows \r\n(два байта) вместо окончания строки Linux \n(один байт).

Может быть, вы запускали эту команду выше под Windows, используя либо такие инструменты, как cygwinили эту новую подсистему Linux для Windows 10? Или ты что-то запускал в Wine?

Byte Commander
источник
эта новая подсистема Windows для Linux ? bash - это всего лишь одна программа для Linux, которая в нем работает; Сортировка не Баш.
user253751
@immibis Вы имеете в виду подсистему Linux для Windows ? Я имел в виду это, но сам еще не слишком интересовался этим, поэтому не пытался исследовать это до сих пор.
Byte Commander
На самом деле это называется подсистема Windows для Linux , но любая из них имеет смысл. (Посмотрите, как это будет выглядеть с другой подсистемой: «Подсистема Windows для консоли [Приложения]» или «Подсистема консоли [Приложение] для Windows» имеет смысл)
user253751
@immibis Ага, хорошо. Видите ли, я еще не слишком интересовался этой конкретной темой. Прости меня, пожалуйста :)
Byte Commander