Classifique os dados em ordem decrescente da primeira coluna, para valores iguais, use a segunda coluna em ordem crescente

22

Permitam-me esclarecer:

Suponha que eu tenho algumas palavras-chave com frequência de uso:

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

O que eu quero é classificar esses dados com base na frequência em ordem decrescente e, se houver alguns valores iguais, ele deverá usar a segunda coluna em ordem crescente.

sort -n -r foo.txt

A primeira parte, mas a segunda coluna também são reversed:

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

Como posso obter os seguintes resultados?

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

Eu acho que tenho que usar -kargumentos, mas não consigo descobrir como!

Eu quero saber como isso pode ser feito usando apenas o sortcomando de bash. No entanto, se não for possível conseguir isso apenas sort, outros comandos devem ser compatíveis com o shell Bourne.

Pouya
fonte
[Um pouco OT]: embora equivalente para esses dados em particular, usar a opção GNU-sort -g(numérico geral) em vez de -npara comparações numéricas é mais seguro: funciona corretamente para ponto flutuante e números inteiros.
Arielf

Respostas:

32

Especifique as chaves de classificação separadamente com os critérios:

sort -k1,1nr -k2,2 inputfile

Isso especifica que a primeira chave é classificada numericamente na ordem inversa, enquanto a segunda é classificada de acordo com a ordem de classificação padrão .

Citando a partir da classificação POSIX :

-k keydef

O argumento keydef é uma definição de campo de chave de classificação restrita. O formato desta definição é:

field_start [ type ] [ , field_end [ type ]]

em que field_start e field_end definem um campo-chave restrito a uma parte da linha (consulte a seção DESCRIÇÃO ESTENDIDA) e type é um modificador da lista de caracteres 'b', 'd', 'f', 'i', ' n ',' r '. O modificador 'b' deve se comportar como a -bopção, mas deve ser aplicado apenas ao field_start ou field_end ao qual está anexado. Os outros modificadores devem se comportar como as opções correspondentes, mas aplicam-se apenas ao campo-chave ao qual estão anexados; eles terão esse efeito se especificados com field_start , field_end ou ambos., nenhuma opção se aplica a nenhum dos dois. As implementações devem suportar pelo menos nove ocorrências da -kopção, que devem ser significativas na ordem da linha de comando. Se nenhuma -kopção for especificada, uma chave de classificação padrão de toda a linha deve ser usada.

Quando houver vários campos de chave, as chaves posteriores serão comparadas somente depois que todas as chaves anteriores forem iguais. Excepto quando a -uopção for especificado, as linhas que de outra forma compare igual devem ser ordenados como se nenhuma das opções -d, -f, -i, -n, ou -kestavam presentes (mas com -r ainda com efeito, se foi especificada) e com todos os bytes em linhas significativas para o comparação. A ordem na qual as linhas que ainda se comparam são escritas não é especificada.

Isso produziria:

42 Life
17 Stackoverflow
12 Hi
9  LaTeX
9  Superuser
9  Ubuntu
7  C++
7  Hash
devnull
fonte
Obrigado. Fiz o truque. Tem que esperar 10 minutos para aceitar!
Pouya 31/03
@StephaneChazelas Obrigado por apontar; atualizou a referência.
devnull