Perché il mio file ordinato è più grande?


28

Ho un file di testo 2958616 byte. Quando corro sort < file.txt | uniq > sorted-file.txt, ottengo un file di testo a 3213965 byte. Perché il mio file di testo ordinato è più grande?

Puoi scaricare i file di testo qui .


5
Il file di output ha \r\nterminazioni di riga, mentre il file di input ha \nterminazioni di riga. Forse dovresti impostare le impostazioni internazionali in modo diverso. Prova LC_ALL=Cdavanti a ciascun comando.
Meuh

2
@meuh Era così! Potresti aggiungerlo come risposta?
wb9688,

5
Aspetta, le impostazioni locali influiscono su questo? Quale locale stai usando? Qual è l'output di locale? Sei sicuro di non aver creato il file su un altro sistema?
terdon,

6
sed '/^[a-z]*$/d' < file.txt | wc -l mi ha dato 305 righe.
Meuh

5
Il tuo file contiene anche â ê î ñ ô ö öö ûquelli che non sono nel set ASCII.
Terdon,

Risposte:


42

Mentre il tuo file originale ha delle righe che finiscono con \n, il tuo file ordinato ha \r\n. L'aggiunta di \rè ciò che cambia la dimensione.

Per illustrare, ecco cosa succede quando eseguo il comando sul mio sistema 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

Come puoi vedere, il file de-duped ordinato è più corto di alcune righe e, di conseguenza, più piccolo di alcuni byte. Il tuo file, tuttavia, è diverso:

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

I due file hanno esattamente lo stesso numero di righe, ma:

$ 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

Quello che sorted-file.txtho scaricato dal tuo link è più grande. Se ora esaminiamo la prima riga, possiamo vedere l'extra \r:

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

Che non sono presenti in quello che ho creato su Linux:

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

Se ora rimuoviamo il \rfile dal tuo file:

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

Otteniamo il risultato atteso, un file più piccolo dell'originale, proprio come quello che ho creato sul mio sistema:

$ 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
Come mai il comando sort ha aggiunto il file risultante? La combinazione di Windows Plus non è una cosa?
Tulains Córdova,

3
@ TulainsCórdova è un'ottima domanda. Non ne ho idea. Suppongo che l'OP abbia fatto questo in un ambiente non nativo, ma non lo so. E sì, le \r\nterminazioni di riga sono una cosa di Windows.
terdon,

25

hexdump lo rivela!

$ 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   

Il file ordinato è più grande perché utilizza le terminazioni di linea di Windows \r\n(due byte) anziché le terminazioni di linea di Linux \n(un byte).

Potrebbe essere che stavi eseguendo quel comando sopra in Windows usando strumenti simili cygwino questo nuovo sottosistema Linux per Windows 10? O hai forse eseguito qualcosa in Wine?


questo nuovo sottosistema Windows per Linux ? bash è solo un programma Linux in esecuzione; l'ordinamento non è bash.
user253751

@immibis Vuoi dire sottosistema Linux per Windows ? Volevo dire questo, ma non sono stato ancora troppo interessato a me stesso, quindi non ho provato o ricercato ulteriormente finora.
Byte Commander

In realtà si chiama sottosistema Windows per Linux , ma uno dei due ha senso. (Guarda come apparirebbe con un altro sottosistema: "Sottosistema Windows per console [Applicazioni]" o "Sottosistema console [Applicazione] per Windows" ha senso)
user253751

@immibis Aha, ok. Vedi, non ero ancora troppo interessato a quell'argomento specifico. Perdonami, per favore :)
Byte Commander
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.