web-dev-qa-db-fra.com

Comment utiliser le tri sur une commande d'impression awk?

J'ai quelques commandes dans un script awk que j'écris:

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

Quelles sorties:

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

Comment utiliser la commande sortdans mon script awk pour trier UNIQUEMENT les joueurs et leurs numéros?

7
KMoy

vous pouvez ajouter | sort -k2 à votre commande. Cela triera alphabétiquement sur la deuxième colonne.

Exemple:

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

résulte en

Kobe Bryant 24
Kevin Durant 35
Blake Griffin 32
Lebron James 23
Dikembe Mutumbo 55
9
Wayne_Yux

Bien que je ne le recommande pas (compte tenu de la simplicité relative du traitement du résultat via une commande externe sortname__), vous pouvez le faire au moins avec les versions récentes de GNU awk (au moins 4.0 IIRC), comme décrit à la section Tri des valeurs et des indices de tableau avec gawk

Voici comment vous pouvez l'implémenter, en supposant que vous disposiez des données dans un tableau associatif dans lequel l'index est Firstname Lastname. Vous devez d’abord définir une fonction de comparaison personnalisée qui divise l’index, la compare d’abord à Lastnamename__, puis (en tant que point de départ) à Firstnamename__, par exemple.

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;
}

Vous pouvez maintenant utiliser la méthode de tri de tableaux PROCINFO["sorted_in"] mentionnée dans les commentaires par @zwets.

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

Mettre ensemble

#!/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[$1" "$2] = $3;
}

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

Essai:

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

Dans les versions moins anciennes ou plus anciennes de awk, la meilleure solution consiste peut-être à stocker les données indexées par Lastname Firstname, à trier avec le nom conventionnel asortiname__, puis à séparer et échanger les champs des index lorsque vous parcourez le tableau pour les imprimer:

awk '
  {a[$2" "$1]=$3} 
  END {
    n=asorti(a,b); for (i=1;i<=n;i++) {split(b[i],s); print s[2], s[1], a[b[i]]}
}' yourfile
8
steeldriver

Pour sort uniquement par le second champ séparé par des espaces, utilisez la clé -k2,2:

... | sort -k2,2

par défaut, sort effectue le tri lexicographiquement.

Notez que, si vous ne mentionnez pas le dernier champ de la clé de tri, c’est-à-dire que vous utilisez simplement -k2, vous risquez de ne pas obtenir le résultat souhaité, car sort sera comme suit tous les champs à partir de la seconde.

Cochez également man sort.

5
heemayl

pour trier vos données à imprimer:

supposons que vous vouliez imprimer le deuxième champ (séparez les espaces) utilisez ceci ::

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

par exemple:

---Terminal----

$cat>data.txt

1 kédar 20

2 Amit 30

3 Rahul 21

^ C

$awk '{print $2}' |sort

Amit

Kedar

Rahul


Si vous souhaitez imprimer l’ensemble de votre fichier data.txt mais trié sur la colonne 2

puis

-----Terminal-----

$awk '{print}'|sort -k2

2 Amit 30

1 kédar 20

3 Rahul 21

Utilisez cette logique dans vos besoins.

Vous pouvez utiliser le type homme pour des fonctionnalités plus intéressantes. !!!

Amusez-vous avec UNIX/LINUX !!

1

Essayer

awk -f myscript.awk | sort -k2

Où myscript.awk contient des commandes purement awk.

Si votre script réel est un script Shell, vous disposez de plusieurs options, notamment

  • Sortie de tuyau par tri. ./myscript.bash | sort -k2
  • Réécrire le code en tant que fonction dans le script
    Au lieu de

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

    Faire

    $ 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
    

Mais notez que vous pouvez également appliquer le tri à la structure do ... done au lieu de créer une fonction.

    do
       echo $i
    done | sort
1
RedGrittyBrick