Pourquoi mon fichier trié est-il plus gros?

28

J'ai un fichier texte de 2958616 octets. Lorsque je cours sort < file.txt | uniq > sorted-file.txt, j'obtiens un fichier texte de 3213965 octets. Pourquoi mon fichier texte trié est-il plus gros?

Vous pouvez télécharger les fichiers texte ici .

wb9688
la source
5
Votre fichier de sortie a des \r\nfins de ligne, tandis que le fichier d'entrée a des \nfins de ligne. Vous devriez peut-être définir vos paramètres régionaux différemment. Essayez LC_ALL=Cdevant chaque commande.
meuh
2
@meuh C'était tout! Pourriez-vous ajouter cela comme réponse?
wb9688
5
Attendez, les paramètres régionaux affectent cela? Quels paramètres régionaux utilisez-vous? Quelle est la sortie de locale? Êtes-vous sûr de ne pas avoir créé le fichier sur un autre système?
terdon
6
sed '/^[a-z]*$/d' < file.txt | wc -l m'a donné 305 lignes.
meuh
5
Votre fichier contient également â ê î ñ ô ö öö ûceux qui ne sont pas dans l'ensemble ASCII.
terdon

Réponses:

42

Alors que votre fichier d'origine contient des lignes se terminant par \n, votre fichier trié en a \r\n. L'ajout du \rest ce qui change la taille.

Pour illustrer, voici ce qui se passe lorsque j'exécute votre commande sur mon système 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

Comme vous pouvez le voir, le fichier trié dupé est plus court de quelques lignes et, par conséquent, de quelques octets plus petit. Votre dossier est cependant différent:

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

Les deux fichiers ont exactement le même nombre de lignes, mais:

$ 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

Le sorted-file.txt, celui que j'ai téléchargé à partir de votre lien, est plus grand. Si nous examinons maintenant la première ligne, nous pouvons voir le supplément \r:

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

Qui ne sont pas présents dans celui que j'ai créé sur Linux:

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

Si nous supprimons maintenant le \rfichier de votre fichier:

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

Nous obtenons le résultat attendu, un fichier plus petit que l'original, tout comme celui que j'ai créé sur mon système:

$ 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
la source
3
Comment se fait-il que la commande de tri ait été ajoutée \ r au fichier résultant? La combinaison de \ r plus \ na n'est-elle pas quelque chose de Windows?
Tulains Córdova
3
@ TulainsCórdova c'est une très bonne question. Je n'ai aucune idée. Je suppose que l'OP l'a fait dans un environnement non natif mais je ne sais pas. Et oui, les \r\nfins de ligne sont une chose Windows.
terdon
25

hexdump le révèle!

$ 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   

Votre fichier trié est plus volumineux car il utilise des fins de ligne Windows \r\n (deux octets) au lieu des fins de ligne Linux \n(un octet).

Serait-ce que vous exécutiez cette commande ci-dessus sous Windows en utilisant des outils comme cygwinou ce nouveau sous-système Linux pour Windows 10? Ou avez-vous peut-être exécuté quelque chose dans Wine?

Byte Commander
la source
ce nouveau sous-système Windows pour Linux ? bash n'est qu'un programme Linux qui s'exécute dedans; le tri n'est pas bash.
user253751
@immibis Vous voulez dire le sous-système Linux pour Windows ? Je le pensais, mais je ne m'y suis pas trop intéressé pour l'instant, donc je n'ai pas essayé ou recherché plus loin jusqu'à présent.
Byte Commander
Il est en fait appelé le sous-système Windows pour Linux , mais l'un ou l'autre est logique. (Voir à quoi cela ressemblerait avec un autre sous-système: "Sous-système Windows pour console [Applications]" ou "Sous-système console [Application] pour Windows" est logique)
user253751
@immibis Aha, d'accord. Vous voyez, je n'étais pas encore trop intéressé par ce sujet spécifique. Pardonnez-moi, s'il vous plaît :)
Byte Commander