Mengapa file saya yang diurutkan lebih besar?

28

Saya memiliki file teks 2958616 byte. Ketika saya menjalankan sort < file.txt | uniq > sorted-file.txt, saya mendapatkan file teks 3213965 byte. Mengapa file teks saya yang diurutkan lebih besar?

Anda dapat mengunduh file teks di sini .

wb9688
sumber
5
File output Anda memiliki \r\nakhir baris, sedangkan file input memiliki \nakhir baris. Mungkin Anda harus mengatur lokasi Anda secara berbeda. Coba LC_ALL=Cdi depan setiap perintah.
meuh
2
@meuh Itu dia! Bisakah Anda menambahkan itu sebagai jawaban?
wb9688
5
Tunggu, lokal memengaruhi ini? Lokal apa yang Anda gunakan? Apa output dari locale? Anda yakin tidak membuat file di sistem lain?
terdon
6
sed '/^[a-z]*$/d' < file.txt | wc -l memberi saya 305 baris.
meuh
5
File Anda juga mengandung â ê î ñ ô ö öö ûyang tidak ada dalam set ASCII.
terdon

Jawaban:

42

Sementara file asli Anda memiliki garis yang berakhir dengan \n, file Anda yang diurutkan memiliki \r\n. Penambahan \rinilah yang mengubah ukuran.

Sebagai ilustrasi, inilah yang terjadi ketika saya menjalankan perintah Anda di sistem Linux saya:

$ 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

Seperti yang Anda lihat, file de-duped yang diurutkan lebih pendek beberapa baris dan, akibatnya, beberapa byte lebih kecil. Namun file Anda berbeda:

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

Kedua file memiliki jumlah baris yang persis sama, tetapi:

$ 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

Yang sorted-file.txtsaya unduh dari tautan Anda lebih besar. Jika sekarang kita memeriksa baris pertama, kita dapat melihat tambahan \r:

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

Yang tidak ada dalam yang saya buat di Linux:

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

Jika sekarang kami menghapus \rdari file Anda:

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

Kami mendapatkan hasil yang diharapkan, file yang lebih kecil dari aslinya, sama seperti yang saya buat di sistem saya:

$ 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
sumber
3
Kenapa perintah sortir ditambahkan ke file yang dihasilkan? Bukankah kombinasi Windows plus?
Tulains Córdova
3
@ TulainsCórdova itu pertanyaan yang sangat bagus. Saya tidak punya ide. Saya berasumsi OP melakukan ini di lingkungan non-pribumi tapi saya tidak tahu. Dan ya, \r\nakhiran baris adalah hal Windows.
terdon
25

hexdump mengungkapkannya!

$ 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   

File Anda yang diurutkan lebih besar karena menggunakan ujung baris Windows \r\n(dua byte) daripada ujung baris Linux \n(satu byte).

Mungkinkah Anda menjalankan perintah di atas di bawah Windows menggunakan alat seperti cygwinatau subsistem Linux baru ini untuk Windows 10? Atau apakah Anda mungkin menjalankan sesuatu di Wine?

Komandan Byte
sumber
ini Subsistem Windows baru untuk Linux ? bash hanya satu program Linux yang berjalan di dalamnya; sort bukan bash.
user253751
@immibis Maksud Anda subsistem Linux untuk Windows ? Maksud saya itu, tetapi saya belum terlalu tertarik dengan hal itu, jadi jangan mencoba atau meneliti lebih jauh sejauh ini.
Byte Commander
Ini sebenarnya disebut Subsistem Windows untuk Linux , tetapi keduanya masuk akal. (Lihat bagaimana ini akan terlihat dengan subsistem lain: "Subsistem Windows untuk Konsol [Aplikasi]" atau "Subsistem [Aplikasi] Konsol untuk Windows" masuk akal)
user253751
@immibis Aha, oke. Anda lihat saya belum terlalu tertarik dengan topik spesifik itu. Maafkan saya, tolong :)
Byte Commander