Urutkan data dalam urutan kolom pertama menurun, untuk nilai yang sama, gunakan kolom kedua dalam urutan naik

22

Izinkan saya mengklarifikasi:

Asumsikan saya memiliki beberapa kata kunci dengan frekuensi penggunaannya:

12 Hi
7  Hash
7  C++  
9  Superuser
17 Stackoverflow
9  LaTeX  
42 Life
9  Ubuntu

Yang saya inginkan, adalah menyortir data ini berdasarkan frekuensi dalam urutan menurun dan jika ada beberapa nilai yang sama, itu harus menggunakan kolom kedua dalam urutan naik.

sort -n -r foo.txt

Apakah bagian pertama tetapi kemudian kolom kedua juga reversed:

42 Life
17 Stackoverflow
12 Hi
9  Ubuntu
9  Superuser
9  LaTeX  
7  Hash
7  C++

Bagaimana saya bisa mencapai hasil berikut?

42 Life
17 Stackoverflow
12 Hi
9  LaTeX  
9  Superuser
9  Ubuntu
7  C++ 
7  Hash

Saya pikir saya harus menggunakan -kargumen tetapi saya tidak tahu caranya!

Saya ingin tahu bagaimana ini bisa dilakukan hanya dengan menggunakan sortperintah bash. Namun jika tidak mungkin untuk mencapai ini hanya dengan sort, perintah lain harus kompatibel dengan Bourne shell.

Pouya
sumber
[Agaknya OT]: meskipun setara untuk data khusus ini, menggunakan -gopsi sortir-GNU (angka umum) alih-alih -nuntuk perbandingan numerik lebih aman: ia bekerja dengan benar untuk floating point dan integer.
arielf

Jawaban:

32

Tentukan kunci pengurutan secara terpisah dengan kriteria:

sort -k1,1nr -k2,2 inputfile

Ini menentukan bahwa kunci pertama diurutkan secara numerik dalam urutan terbalik sedangkan yang kedua diurutkan sesuai urutan urutan default .

Mengutip dari POSIX sort :

-k keydef

The keydef argumen adalah definisi bidang semacam kunci dibatasi. Format definisi ini adalah:

field_start [ type ] [ , field_end [ type ]]

di mana field_start dan field_end mendefinisikan bidang kunci yang dibatasi pada bagian garis (lihat bagian DESKRIPSI TERPANJANG), dan ketik adalah pengubah dari daftar karakter 'b', 'd', 'f', 'i', ' n ',' r '. Pengubah 'b' akan berperilaku seperti -bopsi, tetapi hanya berlaku untuk field_start atau field_end yang dilampirkan. Pengubah lain harus berperilaku seperti opsi yang sesuai, tetapi hanya berlaku untuk bidang kunci yang dilampirkan; mereka akan memiliki efek ini jika ditentukan dengan field_start , field_end , atau keduanya., tidak ada opsi yang berlaku untuk keduanya. Implementasi harus mendukung setidaknya sembilan kemunculan -kopsi, yang harus signifikan dalam urutan baris perintah. Jika tidak ada -kopsi yang ditentukan, kunci sortir default dari seluruh baris harus digunakan.

Ketika ada beberapa bidang kunci, kunci nanti harus dibandingkan hanya setelah semua kunci sebelumnya membandingkan sama. Kecuali jika -upilihan ditentukan, garis-garis yang lain membandingkan sama harus dipesan sebagai jika tidak ada pilihan -d, -f, -i, -n, atau -khadir (tapi dengan -r masih berlaku, jika ditentukan) dan dengan semua byte dalam garis yang signifikan terhadap perbandingan. Urutan di mana baris yang masih membandingkan sama ditulis tidak ditentukan.

Ini akan menghasilkan:

42 Life
17 Stackoverflow
12 Hi
9  LaTeX
9  Superuser
9  Ubuntu
7  C++
7  Hash
devnull
sumber
Terima kasih. Lakukan triknya. Harus menunggu 10 menit untuk menerima!
Pouya
@StephaneChazelas Terima kasih telah menunjukkannya; memperbarui referensi.
devnull