Urutkan file CSV berdasarkan prioritas kolom menggunakan perintah "urutkan"

95

Saya memiliki file csv, dan saya ingin mengurutkan berdasarkan prioritas kolom, seperti "pesan berdasarkan". Sebagai contoh:

3;1;2
1;3;2
1;2;3
2;3;1
2;1;3
3;2;1

Jika situasi ini adalah hasil dari "pilih", "urutkan berdasarkan" adalah sebagai berikut: urutkan menurut kolom2, kolom1, kolom3 - hasilnya adalah:

2;1;3
3;1;2
1;2;3
3;2;1
1;3;2
2;3;1

Saya ingin tahu bagaimana mendapatkan hasil yang sama dengan menggunakan perintah "sort" di Unix.

Rafael Orágio
sumber
4
Omong-omong, itu adalah file ssv (nilai dipisahkan titik koma): P
John Strood

Jawaban:

157
sort --field-separator=';' --key=2,1,3
Charlie Martin
sumber
9
Jika nilainya numerik, maka Anda mungkin ingin mempertimbangkan untuk menggunakan -nopsi yang akan "membandingkan sesuai dengan nilai numerik string" atau -gopsi yang akan "membandingkan sesuai dengan nilai numerik umum". Perbandingan string nilai numerik akan mendapatkan angka yang diurutkan seperti 1,10,2,20. Setidaknya itu adalah opsi yang tersedia di versi sortir saya di CentOS. Anda harus memverifikasi dengan halaman manual opsi apa yang benar pada versi sortir Anda.
Adam Porad
5
Saya mendapatkansort: stray character in field spec: invalid field specification ‘2,1,3’
Martin Thoma
3
Namun, sort --field-separator=',' -r -k3 -k1 -k2 source.csv > target.csvberhasil untuk saya.
Martin Thoma
6
@MartinThoma sudah lama sekali tetapi saya mengalami masalah Anda dan saya menemukannya sort --field-separator=';' --key={2,1,3}. Ini bekerja GNU coreutils 8.4mulai April 2016
mrbolichi
3
@mrbolichi notasi --key={2,1,3}menggunakan ekspansi penjepit dari bash
kvantour
29

Misalkan Anda memiliki baris lain 3;10;3di unsorted.csvfile Anda . Maka saya kira Anda mengharapkan hasil yang diurutkan secara numerik:

2;1;3
3;1;2
1;2;3
3;2;1
1;3;2
2;3;1
3;10;3

dan bukan yang diurutkan menurut abjad:

2;1;3
3;1;2
3;10;3
1;2;3
3;2;1
1;3;2
2;3;1

Untuk mendapatkannya, Anda harus menggunakan -n:

sort --field-separator=';' -n -k 2,2 -k 1,1 -k 3,3 unsorted.csv

Perlu disebutkan bahwa 2,2harus digunakan. Jika hanya 2digunakan, maka sortambil string dari awal field 2 sampai akhir. 2,2pastikan hanya kolom 2yang digunakan.

Martin Thoma
sumber
8
Penunjuk untuk perbedaan antara -k 2, dan -k 2,2 adalah signifikan! Saya telah melewatkan ini pada pembacaan pertama halaman manual. Terima kasih.
usonianhorizon
Saya menambahkan beberapa baris tambahan, 3;10;3, 3:10:5, 3:10;2, 3;10;3agar di file sumber, dan ketika menggunakan hanya -k 2,2 muncul untuk menyortir pada kolom 2 dan 3. halaman manual mengatakan "The -k option may be specified multiple times, in which case subsequent keys are compared when earlier keys compare equal.". Dalam kasus saya, kunci sebelumnya (nilai = 10) membandingkan sama, namun, saya tidak menentukan -kbeberapa kali. Saya tidak yakin apakah ini perilaku yang dapat diandalkan, atau terkait dengan sistem saya (mac). Pada akhirnya itu tidak masalah, selama penyortiran utama benar.
Davos
Oh saya lihat ada juga -sjenis stable yang mengabaikan tombol yang sama, yang menurut manusia lebih cepat.
Davos
24

Jawaban Charlie di atas tidak berhasil untuk saya di Cygwin (urutkan versi 2.0, textutils GNU), berikut ini:

sort -t"," -k2 -k1 -k1
Samuel Kerrien
sumber
3
Cygwin memiliki semacam versi yang lebih lama. Seperti biasa, halaman manual adalah teman Anda.
Charlie Martin
2
Saya setuju dengan @CharlieMartin, Anda harus memeriksa halaman manual di sistem Anda. Di CentOS saya menggunakansort --field-separator=';' -k2 -k1 -k3 test.csv
Adam Porad
-6

..dan jika ada yang mengikuti solusi 'urutkan' tetapi sekarang ingin mendapatkan lebih dari satu entri unik per baris (yaitu jumlah X entri unik teratas), setelah Anda mengurutkan file menggunakan 'urutkan', Anda dapat menggunakan aplikasi kecil yang saya buat di sini:

https://github.com/danieliversen/MiscStuff/blob/master/scripts/findTopUniques.java

Daniel Iversen
sumber
2
Bagus untukmu! Tetapi dalam kasus Anda, Anda bisa saja menggunakan cat unsorted-file | sort | uniq | head -X- kapan Xjumlah baris pertama yang ingin Anda hasilkan.
Slavik Meltser
@SlavikMe Terima kasih banyak atas komentarnya! Namun, saran Anda memberikan hasil yang berbeda .. Saran Anda mendapatkan baris X pertama dalam file yang diurutkan seluruhnya, sedangkan kami ingin mendapatkan baris X pertama per "kunci" (yaitu jika Anda memiliki CSV dengan nama, maka jika Anda mengurutkan dengan kolom 2 "nama belakang" maka perintah Anda mungkin hanya akan mendapatkan 3 baris dengan "Allen" sebagai nama belakang sedangkan perintah kami akan mendapatkan "Allen", "Brittain", "Charles" dll). Terimakasih Meskipun!
Daniel Iversen
6
Anda salah. Saya akan menyarankan untuk mencoba perintah yang saya tulis sebelum berkomentar. Perhatikan, bahwa ada perintah uniqdalam urutan pipa, antara the sortdan the head, yang memberikan keunikan pada semua baris yang diurutkan tepat sebelum ekstraksi baris atas.
Slavik Meltser