use a classificação GNU para classificar por uma única chave / impedir a classificação indesejada de outras chaves

9

Eu tenho um arquivo que já contém dados ordenados e gostaria de reordenar o arquivo de acordo com os valores em uma chave, sem destruir a ordem dos dados nas outras chaves.

Como impedir que a classificação GNU execute a classificação de linhas com base nos valores das chaves que eu não especificou, ou como faço para especificar a classificação GNU para ignorar um intervalo de chaves durante a classificação?

Arquivo data.txt:

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

Saída esperada:

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

Comando:

sort -k 1,1 <data.txt

Resultado: classificação indesejada Não pedi:

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

Respostas:

21

Você precisa de uma classificação estável . De man sort:

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

viz .:

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

Observe que você provavelmente também deseja a -nou --numeric-sortse sua chave é numérica (por exemplo, você pode obter resultados inesperados ao comparar 10 a 2 com a ordem de classificação lexical padrão). Nesse caso, é apenas uma questão de fazer:

sort -sn <data.txt

Não é necessário extrair o primeiro campo, pois a interpretação numérica de toda a linha será a mesma do primeiro campo.

chave de aço
fonte
Eu li os documentos, mas a definição adequada de "estável" evitou minha atenção. Obrigado pela resposta rápida, concisa e bem citada. A primeira chave dos dados reais é uma string localizada, portanto, numérico não funcionaria para mim.
Wil
4

Para sortimplementações (não GNU) que não possuem uma -sopção, você sempre pode:

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

Ou seja, anexe o número da linha para torná-la a segunda chave de classificação e retire-a depois.

Stéphane Chazelas
fonte