Classificar com espaço em branco desigual na primeira coluna

2

Eu preciso classificar esta lista pelo nome, alta temp e baixa temp:

Kuala Lumpur 78 56
Seoul 85 66
Karachi 95 75
Tokyo 85 60
Lahore 85 75
Manila 90 85

Eu percebi que o espaço em branco é o delimitador de uma coluna.          %código% o que me dá isso:

Karachi         95 75
Kuala Lumpur    78 56
Lahore          85 75
Manila          90 85
Seoul           85 66
Tokyo           85 60

Mas o "Kuala Lumpur" está causando problemas por causa do espaço.

Então eu tentei tratar "Lumpur" como uma coluna e classificar o primeiro conjunto de números que fiz

sort -k 3n

mas eu entendo isso:

Tokyo           85 60
Seoul           85 66
Karachi         95 75
Lahore          85 75
Kuala Lumpur    78 56 <---Why is this out of order?
Manila          90 85

Como faço para lidar com esse espaço?

    
por healix 01.04.2013 / 21:07

3 respostas

3

Como outros comentaram, será mais fácil trabalhar com os dados se forem valores separados por vírgula (CSV).

Aqui está minha solução para converter os dados em CSV:

$ cat file | sed 's/ \([0-9]\)/,/g' 
Kuala Lumpur,78,56
Seoul,85,66
Karachi,95,75
Tokyo,85,60
Lahore,85,75
Manila,90,85

Substitui qualquer espaço que precede um dígito por uma vírgula. referencia o grupo ([0-9]), o dígito após o espaço. A partir daí, você pode usar sort com o argumento -t para especificar um separador de campo.

$ cat file | sed 's/ \([0-9]\)/,/g' | sort -t, -k2  
Kuala Lumpur,78,56
Tokyo,85,60
Seoul,85,66
Lahore,85,75
Manila,90,85
Karachi,95,75

Se você quiser converter de volta para espaços ou criar uma tabela, veja dois exemplos:

$ cat test | sed 's/ \([0-9]\)/,/g' | sort -t, -k2 | tr , ' '
Kuala Lumpur 78 56
Tokyo 85 60
Seoul 85 66
Lahore 85 75
Manila 90 85
Karachi 95 75

$ cat test | sed 's/ \([0-9]\)/,/g' | sort -t, -k2 | column -s, -t 
Kuala Lumpur  78  56
Tokyo         85  60
Seoul         85  66
Lahore        85  75
Manila        90  85
Karachi       95  75
    
por 01.04.2013 / 22:12
3
awk '{print $NF,$0}' file.txt | sort -nr -k1 | cut -d' ' -f2-
  • $NF : número de campos, $0 : linha inteira
  • sort -nr : reversão numérica (decrescente)
  • sort -k1 : classificar pela primeira coluna (delimitada por sequências de espaços e tabulações)
  • cut -d : delimitador (o padrão é a guia)
  • cut -f2- : fields 2 to last (não reduz nem elimina delimitadores)
ruby -e 'puts readlines.sort_by{|l|l.split[-1].to_i}.reverse' file.txt
  • readlines = ARGF.readlines
  • split divide no espaço em branco por padrão
por 01.04.2013 / 23:44
2

Se você puder alterar seu arquivo para ter colunas separadas por tabulações, sua vida será mais fácil. Se a mudança do arquivo não for uma opção, este perl one-liner fará isso por você:

perl -ne 's/\s+/\t/g; s/([a-z])\s([a-z])/$1 $2/ig; s/\t$/\n/; print;' file |
  sort -t$'\t' -nk3
Kuala Lumpur    78  56  
Tokyo   85  60  
Seoul   85  66  
Karachi 95  75  
Lahore  85  75  
Manila  90  85  

EXPLICAÇÃO:

  • s/\s+/\t/g : altera TODOS os espaços para TABs.
  • s/([a-z])\s([a-z])/$1 $2/ig : altere TABs que estão entre duas letras (sem números) de volta para espaços únicos.
  • s/\t$/\n/ : a primeira substituição introduz uma ABA no final de cada linha, altere-a de volta para um caractere de nova linha ( \n ).

  • sort -t$'\t' -nk3 : use TAB como delimitador (a classificação tem uma sintaxe estranha, eu sei, veja aqui para mais informações) e classifique numericamente na terceira coluna.

por 01.04.2013 / 21:32

Tags