Cette ligne supprime les lignes en double de la saisie de texte sans tri préalable.
Par exemple:
$ cat >f
q
w
e
w
r
$ awk '!a[$0]++' <f
q
w
e
r
$
Le code original que j'ai trouvé sur les internets se lit comme suit:
awk '!_[$0]++'
Cela me rendait encore plus perplexe alors que je prenais _
une signification particulière dans awk, comme dans Perl, mais il s’est avéré qu’il ne s’agissait que du nom d’un tableau.
Maintenant, je comprends la logique qui se cache derrière une ligne: chaque ligne d’entrée est utilisée comme clé dans un tableau de hachage. Ainsi, une fois terminée, la table de hachage contient des lignes uniques dans l’ordre d’arrivée.
Ce que j'aimerais apprendre, c'est à quel point cette notation est interprétée par awk. Par exemple, ce que signifie le signe bang ( !
) et les autres éléments de cet extrait de code.
Comment ça marche?
Réponses:
Voyons voir,
première
nous regardons la valeur de
a[$0]
(tableaua
avec toute la ligne d'entrée ($0
) comme clé).S'il n'existe pas (la
!
négation dans test sera-t-elle vraie)nous imprimons la ligne de saisie
$0
(action par défaut).De plus, nous ajoutons un (
++
) àa[$0]
, ainsi la prochaine fois!a[$0]
sera évaluée à false.Nice, trouve !! Vous devriez jeter un coup d'œil au code golf!
la source
awk
comme test pour chaque ligne d'entrée; chaque fois que le test réussit,awk
l'action est exécutée entre accolades, ce qui, lorsqu'il est omis, l'est{print}
. Merci!awk
, l'action par défaut est{print $0}
. Cela signifie que tout ce qui est évalué comme vrai l'exécutera par défaut. Ainsi, par exemple,awk '1' file
affiche toutes les lignes,awk '$1' file
toutes les lignes dont le premier champ n'est pas vide ou 0, etc.Voici le traitement:
a[$0]
: regardez la valeur de la clé$0
, dans un tableau associatifa
. S'il n'existe pas, créez-le.a[$0]++
: incrémente la valeur dea[$0]
, renvoie l'ancienne valeur en tant que valeur d'expression. Sia[$0]
n'existe pas, le retour0
et l' incrémenta[$0]
de1
(++
opérateur revient valeur numérique).!a[$0]++
: nie la valeur de l'expression. Sia[$0]++
return0
, l'expression entière est évaluée à true,awk
action effectuée par défautprint $0
. Sinon, l'expression entière est évaluée à false, les causesawk
ne font rien.Les références:
Avec
gawk
, nous pouvons utiliser dgawk (ouawk --debug
avec une version plus récente) pour déboguer ungawk
script. Tout d’abord, créez ungawk
script, nommétest.awk
:Puis lancez:
ou:
Dans la console du débogueur:
Vous pouvez voir, a
Op_postincrement
été exécuté avantOp_not
.Vous pouvez également utiliser
si
ou à lastepi
place des
oustep
pour voir plus clairement:la source
!
est appliquée auparavant++
.!
calcul du résultat de l' opérateur. Vous confondez la priorité des opérateurs (!a[$0]++
est analysée de la même manière!(a[$0]++)
) avec l'ordre d'évaluation (l'attribution de la nouvelle valeur de a lieua[$0]
après le calcul de la valeur de l'expression).!x
est calculée, oùx
est l'ancienne valeur dea[$0]
. Puisa[$0]
est réglé sur1+x
.