awk condición de verdadero y falso

9

Encontré que si usamos awk 0 inputfile, no imprimirá nada porque 0significa falso de la condición.

Si lo usamos awk 1 inputfile, imprimirá todo como 1verdadero para cada línea awk interprete.

Si usamos awk any_string inputfile, no imprimirá nada porque todas las variables awk se inicializaron como cero, por lo tanto, son falsas.

Pero si lo usamos awk any_integer inputfile, se hará realidad e imprimirá cada línea del archivo, ¿puedo saber cuál es el motivo?

Sin embargo, no puedo encontrar que esto se haya explicado en el manual de GNUawk .

sylye
fuente
3
por any_integerlo que supongo número medio literal como 7, 89etc .. Si es así, la razón es cualquier número distinto de 0medios truecondición
Sundeep

Respuestas:

13

Verdadero para awk es una cadena no vacía o un número distinto de cero (con números que son enteros decimales o coma flotante y con algunas implementaciones de awk hexadecimal u octal también son compatibles). Las cosas entre comillas dobles son cadenas, los números literales sin comillas son números, pero para cualquier otra cosa, hay reglas complejas para determinar si algo debe tratarse como una cadena o un número. El awkmanual de GNU tiene un capítulo completo sobre eso .

Cierto:

  • awk '1' (número distinto de cero)
  • awk '1e8' (número distinto de cero)
  • awk '-0.01' (número distinto de cero)
  • awk '"foo"' (cadena no vacía)
  • awk '"0"' (cadena no vacía)
  • awk '0 ""' (la concatenación produce una cadena que aquí no está vacía)
  • echo 0 | awk '$1 ""' (lo mismo para un campo $ n)
  • awk 'substr("000", 1, 1)'(el resultado substr()es siempre una cadena)
  • echo '0foo' | awk '$0' ($ 0 es una cadena no numérica, por lo que se considera una cadena (no vacía))

Falso:

  • awk '0' (Número 0)
  • awk '""' (cuerda vacía)
  • echo 0000e123 | awk '$1' ($ 1 se considera un número si es una cadena numérica que está aquí y es 0)
  • echo ' 0 ' | awk '$0' (los espacios iniciales y finales se ignoran para determinar si una cadena es numérica).
  • awk '" 2foo" - 2' (una cadena involucrada en una expresión aritmética se convierte en un número con algo más allá del número ignorado)
  • awk 'unset_or_empty_variable' (cuerda vacía)
  • awk '"non-numerical-string" + 0'

YMMV:

  • awk '1e-500' (Algunos se quejarán, otros lo tratarán como 0)
  • awk '"0x1" + 0'(no todas las implementaciones de awk admiten hexadecimales, en las que sí "0x1"se convierten 1, en otras a 0. Algunas versiones de la especificación POSIX inadvertidamente requerían implementaciones para admitir ese número hexadecimal allí y se ha retraído más tarde. Todavía gawkreconoce ese número hexadecimal cuando POSIXLY_CORRECTestá en el entorno)
  • awk '010 - 8' (igual (bueno, no del todo, ya que el 010 es literal aquí en lugar de convertirse de una cadena) para los octales)
  • awk '0x1 - 1'(en awkimplementaciones que no admiten números hexadecimales, 0x1es la concatenación de 0y la x1variable que produce "0"que se convierte en un número (0), si resta 1se obtiene -1el número distinto de cero).

Lo que eso significa es que si desea verificar si una cadena no está vacía, no debe hacer lo siguiente:

awk '$ 1 {print $ 1, "no está vacío"}'

Pero

awk '$1 != "" {print $1, "is not empty"}'

De lo contrario, no diría 0o -0000E+00001234no están vacíos.

Stéphane Chazelas
fuente
Impresionante y detallada respuesta! Sin embargo, una pregunta: en el último ejemplo que diste, probé la sintaxis y la primera funciona, donde omite los $ 1 que están vacíos y solo imprime esas líneas con $ 1 no vacío, porque si $ 1 es una cadena vacía, será Falso, y por lo tanto no imprime la salida, ¿no?
sylye