Esta línea única elimina las líneas duplicadas de la entrada de texto sin ordenarlas previamente.
Por ejemplo:
$ cat >f
q
w
e
w
r
$ awk '!a[$0]++' <f
q
w
e
r
$
El código original que he encontrado en Internet dice:
awk '!_[$0]++'
Esto fue aún más desconcertante para mí, ya que asumí _que tenía un significado especial en awk, como en Perl, pero resultó ser solo el nombre de una matriz.
Ahora, entiendo la lógica detrás de una línea: cada línea de entrada se usa como una clave en una matriz de hash, por lo tanto, al finalizar, el hash contiene líneas únicas en el orden de llegada.
Lo que me gustaría aprender es cómo awk interpreta exactamente esta notación. Por ejemplo, qué significa el signo de explosión ( !) y los otros elementos de este fragmento de código.
¿Como funciona?

Respuestas:
Veamos,
primero
nos fijamos en el valor de
a[$0](matrizacon toda la línea de entrada ($0) como clave).Si no existe (si la
!negación en la prueba se evaluará como verdadera)imprimimos la línea de entrada
$0(acción predeterminada).Además, agregamos uno (
++) aa[$0], por lo que la próxima vez!a[$0]se evaluará como falso.Bien, encuentra !! ¡Deberías echar un vistazo al código golf!
fuente
awkcomo una prueba para cada línea de entrada; cada vez que la prueba tiene éxito,awkejecuta la acción entre llaves, que, cuando se omite, es{print}. ¡Gracias!awk, la acción predeterminada es{print $0}. Esto significa que todo lo evaluado como verdadero ejecutará esto como predeterminado. Así, por ejemploawk '1' fileimprime todas las líneas,awk '$1' fileimprime todas esas líneas cuyo primer campo no está vacío o 0, etc.Aquí está el procesamiento:
a[$0]: mira el valor de la clave$0, en una matriz asociativaa. Si no existe, créelo.a[$0]++: incrementa el valor dea[$0], devuelve el valor anterior como valor de expresión. Sia[$0]no existe, devuelva0e incrementea[$0]a1(el++operador devuelve un valor numérico).!a[$0]++: niega el valor de la expresión. Sia[$0]++devuelve0, toda la expresión se evalúa como verdadera, realice laawkacción predeterminada realizadaprint $0. De lo contrario, toda la expresión se evalúa como falsa, las causasawkno hacen nada.Referencias
Con
gawk, podemos usar dgawk (oawk --debugcon una versión más nueva) para depurar ungawkscript. Primero, cree ungawkscript, llamadotest.awk:Entonces corre:
o:
En la consola del depurador:
Puedes ver,
Op_postincrementfue ejecutado antesOp_not.También puede usar
sio enstepilugar desosteppara ver más claramente:fuente
!se aplica antes++.!que se calcula el resultado del operador. Está confundiendo la precedencia del operador (!a[$0]++se analiza como!(a[$0]++)) con el orden de evaluación (la asignación del nuevo valor dea[$0]ocurre después de que se haya calculado el valor de la expresión).!xse calcula el valor , dondexes el valor anterior dea[$0]. Luegoa[$0]se establece en1+x.