Чому мій відсортований файл більший?


28

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

Ви можете завантажити текстові файли тут .


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

3
Як приходить команда сортування додана до отриманого файлу? Чи не поєднання значень \ r плюс \ u Windows?
Тулен Кордова

3
@ TulainsCórdova, це дуже гарне питання. Я поняття не маю. Я припускаю, що ОП це робила в не рідному середовищі, але я не знаю. І так, \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?


ця нова підсистема Windows для Linux ? bash - це лише одна програма Linux, яка працює в ній; сортування не баш.
користувач253751

@immibis Ви маєте на увазі підсистему Linux для Windows ? Я мав на увазі це, але ще не надто зацікавився ним, тому не намагався і не досліджував його далі.
Командир байтів

Це насправді називається підсистема Windows для Linux , але будь-яка має сенс. (Дивіться, як це виглядатиме з іншою підсистемою: або "Підсистема Windows для консолі [додатки]" або "консоль [додаток] підсистема для Windows" має сенс)
user253751

@immibis Ага, добре. Розумієте, я ще не надто зацікавився цією конкретною темою. Пробачте, будь ласка :)
Байт командир
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.