Como usar a ordenação em um comando awk print?

7

Eu tenho alguns comandos em um script awk que estou escrevendo:

print "Here are some players and their numbers, sorted by last name"
if(sum[x] > 500) {print x, }

Quais resultados:

Here are some players and their numbers, sorted by last name
Lebron James 23
Kevin Durant 35
Kobe Bryant 24
Blake Griffin 32
Dikembe Mutumbo 55

Como posso usar o comando sort no meu script awk para classificar os jogadores e seus números SOMENTE?

    
por KMoy 01.11.2016 / 08:19

5 respostas

9

você pode adicionar | sort -k2 ao seu comando. Isso classificará alfabeticamente com base na segunda coluna.

Exemplo:

$ echo "Lebron James 23
Kevin Durant 35
Kobe Bryant 24
Blake Griffin 32
Dikembe Mutumbo 55" | sort -k2

resulta em

Kobe Bryant 24
Kevin Durant 35
Blake Griffin 32
Lebron James 23
Dikembe Mutumbo 55
    
por Wayne_Yux 01.11.2016 / 08:24
8

Embora eu não recomende (dada a relativa simplicidade de canalizar o resultado através de um comando externo sort ) você pode fazer isso pelo menos com versões recentes do GNU awk (pelo menos 4.0 IIRC), como descrito em < a href="https://www.gnu.org/software/gawk/manual/html_node/Array-Sorting-Functions.html#Array-Sorting-Functions"> Classificando os valores e índices da matriz com gawk

Veja como você pode implementá-lo, supondo que você tenha os dados em uma matriz associativa em que o índice é Firstname Lastname . Primeiro, você precisa definir uma função de comparação personalizada que divida o índice e compare primeiro com Lastname (como desempatador) em Firstname , por exemplo,

function mycmp(ia, va, ib, vb, sa, sb) {
  if(split(toupper(ia), sa) && split(toupper(ib), sb)) {
    if(sa[2] < sb[2]) return -1;
    else if (sa[2] > sb[2]) return 1;
    else {
      # compare first names
      if(sa[1] < sb[1]) return -1;
      else if (sa[1] > sb[1]) return 1;
      else return 0;
    }
  }
  else return 0;
}

Agora você pode usar o método de classificação PROCINFO["sorted_in"] array mencionado nos comentários por @zwets

PROCINFO["sorted_in"] = "mycmp";
for(i in a) print i, a[i];

Colocando tudo junto

#!/usr/bin/gawk -f

function mycmp(ia, va, ib, vb, sa, sb) {
  if(split(toupper(ia), sa) && split(toupper(ib), sb)) {
    if(sa[2] < sb[2]) return -1;
    else if (sa[2] > sb[2]) return 1;
    else {
      # compare first names
      if(sa[1] < sb[1]) return -1;
      else if (sa[1] > sb[1]) return 1;
      else return 0;
    }
  }
  else return 0;
}

{
  a[" "] = ;
}

END {
  PROCINFO["sorted_in"] = "mycmp";
  for(i in a) print i, a[i];
}

Teste:

$ ./namesort.awk yourfile
Kobe Bryant 24
Kevin Durant 35
Blake Griffin 32
Lebron James 23
Dikembe Mutumbo 55

Em versões menores ou mais antigas do awk, sua melhor aposta pode ser armazenar os dados indexados por Lastname Firstname , classificar com o asorti convencional, depois dividir e trocar os campos dos índices conforme você percorre o array para imprima:

awk '
  {a[" "]=} 
  END {
    n=asorti(a,b); for (i=1;i<=n;i++) {split(b[i],s); print s[2], s[1], a[b[i]]}
}' yourfile
    
por steeldriver 01.11.2016 / 15:17
5

Para sort apenas pelo segundo campo separado por espaço em branco, use a tecla -k2,2 :

... | sort -k2,2

por padrão sort faz a classificação lexicograficamente.

Observe que, se você não mencionar o último campo para a chave de classificação, ou seja, se você usar -k2 , talvez não obtenha o resultado desejado, pois sort será de acordo com todos os campos a partir do segundo.

Verifique também man sort .

    
por heemayl 01.11.2016 / 08:29
1

Tente

awk -f myscript.awk | sort -k2

Onde myscript.awk contém comandos puramente awk.

Se o seu script atual for um script de shell, você tem várias opções, incluindo

  • Saída de tubulação por meio de classificação. %código%
  • Reescreva o código como uma função dentro do script
    Em vez de

    $ cat t1
    #!/bin/bash
    for i in 2 4 3 1 5;
    do
      echo $i
    done
    
    $ ./t1
    2
    4
    3
    1
    5
    

    Faça

    $ cat t2
    #!/bin/bash
    function foo {
      for i in 2 4 3 1 5;
      do
        echo $i
      done
    }
    foo | sort
    
    $ ./t2
    1
    2
    3
    4
    5
    

Mas note que você também pode aplicar a classificação à estrutura do ... done em vez de fazer uma função.

    do
       echo $i
    done | sort
    
por RedGrittyBrick 01.11.2016 / 11:19
0

para classificar seus dados para impressão:

suponha que você queira imprimir o 2º campo (espaço em branco separado) use este:

awk '{print $ 2}' data.txt | classificar

por exemplo:

--- terminal ----

$cat>data.txt

1 Kedar 20

2 Amit 30

3 Rahul 21

^ C

$awk '{print }' |sort

Amit

Kedar

Rahul

Se você quiser imprimir todo o seu data.txt, mas classificado na coluna 2

então

----- terminal -----

$awk '{print}'|sort -k2

2 Amit 30

1 Kedar 20

3 Rahul 21

Use essa (s) lógica (s) em seu requisito.

Você pode usar man sort para recursos mais interessantes do tipo.

Divirta-se com o UNIX / LINUX !!

    
por Abdul Sattar Mapara 31.10.2017 / 16:08