użyj GNU sort, aby posortować według jednego klucza / zapobiec niechcianemu sortowaniu innych kluczy

9

Mam plik, który zawiera już zamówione dane i chciałbym ponownie uporządkować plik zgodnie z wartościami w jednym kluczu, bez niszczenia kolejności danych w innych kluczach.

Jak zapobiec sortowaniu według GNU sortowania wierszy na podstawie wartości kluczy, których nie określiłem, lub jak określić sortowanie GNU, aby ignorować zakres kluczy podczas sortowania?

Plik data.txt:

1 Don't
2 C 
1 Sort
2 B
1 Me
2 A

Oczekiwany wynik:

1 Don't
1 Sort
1 Me
2 C
2 B
2 A

Komenda:

sort -k 1,1 <data.txt

Wynik: niechciane sortowanie, o które nie prosiłem:

1 Don't
1 Me
1 Sort
2 A
2 B
2 C
Wil
źródło

Odpowiedzi:

21

Potrzebujesz stabilnego rodzaju . Od man sort:

-s, --stable
       stabilize sort by disabling last-resort comparison

mianowicie.:

$ sort -sk 1,1 <data.txt
1 Don't
1 Sort
1 Me
2 C 
2 B
2 A

Zauważ, że prawdopodobnie chcesz również a -nlub --numeric-sortjeśli twój klucz jest numeryczny (na przykład możesz uzyskać nieoczekiwane wyniki, porównując 10 do 2 z domyślną - leksykalną - kolejnością sortowania). W takim przypadku wystarczy tylko:

sort -sn <data.txt

Nie trzeba wyodrębniać pierwszego pola, ponieważ interpretacja numeryczna całej linii będzie taka sama jak pierwszego pola.

steeldriver
źródło
Przeczytałem dokumentację, ale właściwa definicja „stabilna” umknęła mojej uwadze. Dzięki za szybką, zwięzłą i dobrze cytowaną odpowiedź. Pierwszym kluczem prawdziwych danych jest zlokalizowany ciąg, więc numeryczna nie działałaby dla mnie.
Wil
4

W przypadku sortimplementacji (nie GNU), które nie mają -sopcji, zawsze możesz:

<data.txt awk '{print NR "\t" $0}' | sort -n -k 2,2 -k 1,1 | cut -f 2-

To znaczy, wstaw numer linii, aby stał się drugim kluczem sortowania, a następnie usuń go.

Stéphane Chazelas
źródło