Dlaczego mój posortowany plik jest większy?

28

Mam plik tekstowy o rozmiarze 2958616 bajtów. Po uruchomieniu sort < file.txt | uniq > sorted-file.txtotrzymuję plik tekstowy o rozmiarze 3213965 bajtów. Dlaczego mój posortowany plik tekstowy jest większy?

Możesz pobrać pliki tekstowe tutaj .

wb9688
źródło
5
Plik wyjściowy ma \r\nzakończenia linii, podczas gdy plik wejściowy ma \nzakończenia linii. Być może powinieneś ustawić swoje ustawienia regionalne inaczej. Spróbuj LC_ALL=Cprzed każdym poleceniem.
Meuh
2
@meuh To było to! Czy możesz dodać to jako odpowiedź?
wb9688,
5
Poczekaj, ustawienia regionalne mają na to wpływ? Jakich lokalizacji używasz? Jaka jest wydajność locale? Czy na pewno nie utworzyłeś pliku w innym systemie?
terdon
6
sed '/^[a-z]*$/d' < file.txt | wc -l dał mi 305 linii.
Meuh
5
Twój plik zawiera również â ê î ñ ô ö öö ûte, których nie ma w zestawie ASCII.
terdon

Odpowiedzi:

42

Podczas gdy twój oryginalny plik ma linie, które kończą się \n, twój plik ma \r\n. Dodanie tego, \rco zmienia rozmiar.

Aby to zilustrować, oto co dzieje się, gdy uruchamiam polecenie w moim systemie 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

Jak widać, posortowany wyodrębniony plik ma kilka wierszy krótszych, a tym samym kilka bajtów mniejszych. Twój plik jest jednak inny:

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

Dwa pliki mają dokładnie taką samą liczbę linii, ale:

$ 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

Ten sorted-file.txt, który pobrałem z twojego linku, jest większy. Jeśli teraz przeanalizujemy pierwszą linię, zobaczymy dodatkowe \r:

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

Których nie ma w utworzonym przeze mnie systemie Linux:

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

Jeśli teraz usuniemy \rz twojego pliku:

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

Otrzymujemy oczekiwany wynik, plik mniejszy niż oryginał, tak jak ten, który utworzyłem w moim systemie:

$ 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
źródło
3
W jaki sposób polecenie sort dodało plik r do wynikowego pliku? Czy kombinacja \ r plus \ na Windows nie jest rzeczą?
Tulains Córdova
3
@ TulainsCórdova to bardzo dobre pytanie. Nie mam pojęcia. Zakładam, że OP zrobił to w środowisku nienatywnym, ale nie wiem. I tak, \r\nzakończenia linii są kwestią Windows.
terdon
25

hexdump ujawnia to!

$ 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   

Twój posortowany plik jest większy, ponieważ używa zakończeń linii systemu Windows \r\n(dwa bajty) zamiast zakończeń linii systemu Linux \n(jeden bajt).

Czy to możliwe, że uruchomiłeś to polecenie powyżej w systemie Windows przy użyciu narzędzi takich jak cygwinlub nowego podsystemu Linux dla Windows 10? A może prowadziłeś coś w Wine?

Bajt Dowódca
źródło
ten nowy podsystem Windows dla systemu Linux ? bash jest tylko jednym programem Linux, który w nim działa; sortowanie to nie bash.
user253751,
@immibis Masz na myśli podsystem Linux dla Windows ? Miałem na myśli to, ale sam jeszcze nie byłem tym zainteresowany, więc nie próbowałem ani nie badałem go do tej pory.
Byte Commander
W rzeczywistości nazywa się to Podsystemem Windows dla Linuksa , ale jedno z nich ma sens. (Zobacz, jak by to wyglądało z innym podsystemem: „Podsystem systemu Windows dla konsoli [Aplikacje]” lub „Podsystem konsoli [Aplikacja] dla systemu Windows” ma sens)
user253751
@immibis Aha, dobrze. Widzisz, nie byłem zbyt zainteresowany tym konkretnym tematem. Wybacz mi, proszę :)
Byte Commander