Sortuj dane w porządku malejącym od pierwszej kolumny, aby uzyskać równe wartości, użyj drugiej kolumny w porządku rosnącym

22

Pozwól mi wyjaśnić:

Załóżmy, że mam kilka słów kluczowych z częstotliwością ich użycia:

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

Chcę posortować te dane według częstotliwości w porządku malejącym, a jeśli istnieją jakieś równe wartości, powinna użyć drugiej kolumny w porządku rosnącym.

sort -n -r foo.txt

Czy pierwsza część, ale potem druga kolumna to również reversed:

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

Jak mogę uzyskać następujące wyniki?

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

Myślę, że muszę użyć -kargumentu, ale nie wiem, jak to zrobić!

Chcę wiedzieć, jak to zrobić, korzystając wyłącznie z sortpolecenia bash. Jednak jeśli nie jest to możliwe tylko przez sort, inne polecenia powinny być kompatybilne z powłoką Bourne'a.

Pouja
źródło
[Nieco OT]: chociaż równoważne dla tych konkretnych danych, użycie opcji sortowania GNU -g(ogólna liczba) zamiast -nporównań numerycznych jest bezpieczniejsze: działa poprawnie zarówno dla liczb zmiennoprzecinkowych, jak i liczb całkowitych.
arielf

Odpowiedzi:

32

Podaj klucze sortowania osobno, stosując kryteria:

sort -k1,1nr -k2,2 inputfile

Oznacza to, że pierwszy klucz jest sortowany numerycznie w odwrotnej kolejności, podczas gdy drugi jest sortowany zgodnie z domyślną kolejnością sortowania.

Cytowanie z sortowania POSIX :

-k keydef

Keydef argument jest ograniczony rodzaj kluczowym definicji pola. Format tej definicji to:

field_start [ type ] [ , field_end [ type ]]

gdzie field_start i field_end definiują pole klucza ograniczone do części wiersza (patrz sekcja OPIS ROZSZERZONY), a typ jest modyfikatorem z listy znaków „b”, „d”, „f”, „i”, „ n ',' r '. Modyfikator „b” będzie zachowywał się jak -bopcja, ale będzie miał zastosowanie tylko do pola_start lub zakończenia_do pola, do którego jest dołączony. Pozostałe modyfikatory powinny zachowywać się jak odpowiednie opcje, ale mają zastosowanie tylko do pola klucza, do którego są przyłączone; będą miały ten efekt, jeśli zostaną określone za pomocą parametru field_start , field_end lub oba., żadna opcja nie ma zastosowania do żadnego z nich. Wdrożenia będą obsługiwać co najmniej dziewięć wystąpień -kopcji, które będą istotne w kolejności wiersza poleceń. Jeśli nie -kpodano żadnej opcji, należy użyć domyślnego klucza sortowania całej linii.

Jeśli istnieje wiele pól kluczy, późniejsze klucze będą porównywane dopiero po tym, jak wszystkie wcześniejsze klucze będą równe. Wyjątkiem sytuacji, gdy -uopcja jest określona, linie, które w przeciwnym razie porównanie równa zarządza się, jak gdyby żadna z opcji -d, -f, -i, -n, lub -kbyły obecne (ale -r nadal w efekcie, jeżeli została określona) i ze wszystkimi bajtów w linii znaczące z punktu widzenia porównanie. Kolejność zapisywania wierszy, które nadal są równe, jest nieokreślona.

Spowodowałoby to:

42 Life
17 Stackoverflow
12 Hi
9  LaTeX
9  Superuser
9  Ubuntu
7  C++
7  Hash
diabelnie
źródło
Dzięki. Wykonał lewę. Musisz poczekać 10 minut, aby zaakceptować!
Pouya
@StephaneChazelas Dzięki za wskazanie tego; zaktualizowałem referencję.
devnull