Por que meu arquivo classificado é maior?

28

Eu tenho um arquivo de texto de 2958616 bytes. Quando executo sort < file.txt | uniq > sorted-file.txt, recebo um arquivo de texto de 3213965 bytes. Por que meu arquivo de texto classificado é maior?

Você pode baixar os arquivos de texto aqui .

wb9688
fonte
5
Seu arquivo de saída possui \r\nfinais de linha, enquanto o arquivo de entrada possui \nfinais de linha. Talvez você deva definir seu código de idioma de maneira diferente. Tente LC_ALL=Cna frente de cada comando.
meuh 10/07/16
2
@meuh Foi isso! Você poderia adicionar isso como resposta?
Wb9688
5
Espere, a localidade afeta isso? Que localidade você está usando? Qual é o resultado de locale? Tem certeza de que não criou o arquivo em outro sistema?
terdon
6
sed '/^[a-z]*$/d' < file.txt | wc -l me deu 305 linhas.
Meu16
5
Seu arquivo também contém â ê î ñ ô ö öö ûaqueles que não estão no conjunto ASCII.
terdon 10/07/16

Respostas:

42

Enquanto seu arquivo original possui linhas que terminam com \n, seu arquivo classificado possui \r\n. A adição do \ré o que muda o tamanho.

Para ilustrar, eis o que acontece quando executo seu comando no meu 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

Como você pode ver, o arquivo desduplicado classificado é algumas linhas mais curto e, consequentemente, alguns bytes menor. Seu arquivo, no entanto, é diferente:

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

Os dois arquivos têm exatamente o mesmo número de linhas, mas:

$ 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

O sorted-file.txtque baixei do seu link é maior. Se agora examinarmos a primeira linha, podemos ver o extra \r:

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

Que não estão presentes no que eu criei no Linux:

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

Se agora removermos o \rarquivo do seu arquivo:

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

Obtemos o resultado esperado, um arquivo menor que o original, exatamente como o que eu criei no meu 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
Terdon
fonte
3
Como o comando de classificação foi adicionado ao arquivo resultante? Não é a combinação de \ r plus \ na coisa do Windows?
Tulains Córdova
3
@TulainsCórdova that's a very good question. I have no idea. I am assuming the OP did this in a non-native environment but I don't know. And yes, \r\n line endings are a Windows thing.
terdon
25

hexdump revela isso!

$ 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   

Seu arquivo classificado é maior porque usa finais de linha do Windows \r\n(dois bytes) em vez de finais de linha do Linux \n(um byte).

Será que você estava executando esse comando acima no Windows usando ferramentas como cygwineste novo subsistema Linux para Windows 10? Ou você rodou alguma coisa no Wine?

Byte Commander
fonte
esse novo subsistema Windows para Linux ? bash é apenas um programa Linux que roda nele; a classificação não é festança.
user253751
@immibis Você quer dizer subsistema Linux para Windows ? Eu quis dizer isso, mas ainda não me interessei muito por isso, então não tentei ou pesquisei ainda mais até agora.
Byte Commander
Na verdade, é chamado de Windows Subsystem for Linux , mas qualquer um deles faz sentido. (Veja como isso ficaria com outro subsistema: ou "Windows Subsistema para Console [Applications]" ou "Console [aplicação] Subsistema para Windows" faz sentido)
user253751
@immibis Aha, tudo bem. Você vê que eu ainda não estava muito interessado nesse tópico específico. Perdoe-me, por favor :)
Byte Commander