Warum ist meine sortierte Datei größer?

28

Ich habe eine 2958616-Byte-Textdatei. Beim Ausführen sort < file.txt | uniq > sorted-file.txterhalte ich eine 3213965-Byte-Textdatei. Warum ist meine sortierte Textdatei größer?

Sie können die Textdateien hier herunterladen .

wb9688
quelle
5
Ihre Ausgabedatei hat \r\nZeilenenden, während die Eingabedatei \nZeilenenden hat. Vielleicht solltest du dein Gebietsschema anders einstellen. Versuchen Sie es LC_ALL=Cvor jedem Befehl.
Meuh
2
@meuh Das war es! Könnten Sie das als Antwort hinzufügen?
wb9688
5
Warte, beeinflusst das Gebietsschema dies? Welches Gebietsschema verwenden Sie? Was ist die Ausgabe von locale? Sind Sie sicher, dass Sie die Datei nicht auf einem anderen System erstellt haben?
Terdon
6
sed '/^[a-z]*$/d' < file.txt | wc -l gab mir 305 Zeilen.
Meuh
5
Ihre Datei enthält auch â ê î ñ ô ö öö ûsolche, die nicht im ASCII-Satz enthalten sind.
Terdon

Antworten:

42

Während Ihre ursprüngliche Datei Zeilen enthält, die mit enden \n, enthält Ihre sortierte Datei \r\n. Das Hinzufügen von \rändert die Größe.

Zur Veranschaulichung geschieht Folgendes, wenn ich Ihren Befehl auf meinem Linux-System ausführe:

$ 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

Wie Sie sehen, ist die sortierte de-dupierte Datei einige Zeilen kürzer und folglich einige Bytes kleiner. Ihre Datei ist jedoch anders:

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

Die beiden Dateien haben genau die gleiche Anzahl von Zeilen, aber:

$ 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

Die sorted-file.txt, die ich über Ihren Link heruntergeladen habe, ist größer. Wenn wir jetzt die erste Zeile untersuchen, können wir das Extra sehen \r:

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

Welche sind in dem, den ich unter Linux erstellt habe, nicht vorhanden:

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

Wenn wir jetzt die \raus Ihrer Datei entfernen :

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

Wir erhalten das erwartete Ergebnis, eine Datei, die kleiner als das Original ist, genau wie die, die ich auf meinem System erstellt habe:

$ 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
quelle
3
Wie kommt es, dass der Sortierbefehl der resultierenden Datei hinzugefügt wurde? Ist die Kombination von \ r plus \ na Windows-Sache nicht?
Tulains Córdova
3
@ TulainsCórdova das ist eine sehr gute frage. Ich habe keine Ahnung. Ich gehe davon aus, dass das OP dies in einer nicht einheimischen Umgebung getan hat, aber ich weiß es nicht. Und ja, \r\nZeilenenden sind eine Windows-Sache.
Terdon
25

hexdump enthüllt es!

$ 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   

Ihre sortierte Datei ist größer, weil sie Windows-Zeilenenden \r\n(zwei Bytes) anstelle von Linux-Zeilenenden \n(ein Byte) verwendet.

Könnte es sein, dass Sie diesen Befehl unter Windows mit Tools wie cygwinoder diesem neuen Linux-Subsystem für Windows 10 ausgeführt haben? Oder hast du vielleicht etwas in Wein laufen lassen?

Byte Commander
quelle
dieses neue Windows-Subsystem für Linux ? bash ist nur ein Linux-Programm, das darin ausgeführt wird. sort ist nicht bash.
user253751
@immibis Du meinst Linux-Subsystem für Windows ? Ich meinte das, habe mich aber noch nicht zu sehr dafür interessiert, also habe ich es noch nicht weiter versucht oder erforscht.
Byte Commander
Eigentlich heißt es Windows-Subsystem für Linux , aber beides macht Sinn. (Sehen Sie, wie dies bei einem anderen Subsystem aussehen würde: Entweder "Windows-Subsystem für Konsole [Anwendungen]" oder "Konsolen-Subsystem [Anwendung] für Windows" ist sinnvoll)
user253751
@immibis Aha, okay. Sie sehen, ich habe mich noch nicht zu sehr für dieses spezielle Thema interessiert. Verzeih mir bitte :)
Byte Commander