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 sort
dans mon script awk pour trier UNIQUEMENT les joueurs et leurs numéros?
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
Bien que je ne le recommande pas (compte tenu de la simplicité relative du traitement du résultat via une commande externe sort
name__), 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 à Lastname
name__, puis (en tant que point de départ) à Firstname
name__, 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 asorti
name__, 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
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
.
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 !!
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
./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