Cuando awk recibe"0"como entrada, se comporta de manera diferente en algunos casos. Código a continuación:
var=$1
echo ""; echo -n 'o/p of $1=$1 ==>'; echo $var | awk '$1=$1'
echo "";echo -n 'o/p of {$1=$1;print} ==>';echo $var | awk '{$1=$1;print}'
echo "";echo -n 'o/p of $1==$1 ==>';echo $var | awk '$1==$1'
echo "";echo -n 'o/p of {$1==$1;print} ==>';echo $var | awk '{$1==$1;print}'
La salida con"0" (número cero):
[root@host ~]# sh /tmp/te.sh 0
o/p of $1=$1 ==>
o/p of {$1=$1;print} ==>0
o/p of $1==$1 ==>0
o/p of {$1==$1;print} ==>0
[root@GORJALA ~]#
La salida con"1" (número uno):
[root@host ~]# sh /tmp/te.sh 1
o/p of $1=$1 ==>1
o/p of {$1=$1;print} ==>1
o/p of $1==$1 ==>1
o/p of {$1==$1;print} ==>1
[root@host ~]#
¿Por qué hay una diferencia cuando uso var=0; echo $var | awk '$1=$1'
y var=1; echo $var | awk '$1=$1'
? Todos los números funcionan bien excepto 0
.
Versiones:
- Fiesta GNU, versión 4.2.46
- GNU Awk 4.0.2
- coreutils-8.22-24.el7.x86_64
Respuesta1
Desde elLa guía del usuario de GNU Awk:
Una asignación es una expresión, por lo que tiene un valor: el mismo valor que se asigna. Por tanto, 'z = 1' es una expresión con el valor uno.
Entonces
echo 0 | awk '$1=$1'
el patrón se evalúa como 0 (FALSO)echo 1 | awk '$1=$1'
el patrón se evalúa como 1 (VERDADERO) yprint
se ejecuta la acción predeterminada
Respuesta2
No creo que sea una cuestión de valor numérico: las conversiones estándar se encargan de eso (al menos aquí).
El OP muestra cuatro códigos awk diferentes, todas variaciones de: patrón {acción}
(a) $1 = $1
Eso reasigna $1 a sí mismo. No es una prueba booleana, no es operativa (efectivamente) y devuelve el valor de $1. Si $1 es un 0, el patrón esFALSOy el valor predeterminadola acción de impresión se omite por completo. Si $1 es distinto de cero, ella entrada se imprime.
(b) {$1 = $1; imprimir; }
Eso reasigna $1 a sí mismo, lo que también es una operación no operativa. En ausencia de un patrón, la acción se realiza y la entrada sesiempre impreso.
(c) 1$ == 1$
Esa es una expresión booleana que essiempre cierto. 0 es 0 y 1 es 1 (y oso hormiguero es oso hormiguero). En ausencia de una acción, la entrada essiempre impreso.
(d) { $1 == $1; imprimir; }
No hay ningún patrón. La comparación se evalúa como un valor booleano verdadero que se descarta. La entrada essiempre impreso.
Respuesta3
Las respuestas existentes no explican por qué
echo 0 | awk '$0="0"'
echo 0 | awk '$0=substr($0,1)'
echo 0 | awk '$0=$0""'
todo se imprimirá 0
, pero
echo 0 | awk '$0'
echo 000 | awk '$0'
no imprimirá nada, aunque en todos los casos, la expresión del patrón se evalúa como 0
.
¿Cómo es que 0
es verdadero en un caso y falso en el otro?
Esto se debe a que las "variables de campo" (el resultado del $
operador) se tratan como uncaso especial, y (si es posible) se convierten automáticamente acadenas numéricas, que, si es numéricamente igual a 0
, se considerará falso cuando se use en un contexto booleano:
Un valor de cadena se considerará uncadena numéricasi proviene de uno de los siguientes:
Variables de campo
Entrada de la
getline()
función
FILENAME
ARGV
elementos de matriz
ENVIRON
elementos de matrizElementos de matriz creados por la
split()
función.Una asignación de variable de línea de comando
Asignación de variable desde otra variable de cadena numérica
y [si parece un número, lee la descripción completaaquí]
Por favor lea también elRATIONALE
por las razones por las que se necesitaba el concepto de cadenas numéricas y esta mayúscula especial, especialmente la parte sobre una comparación como si echo 0 000 | awk '$1==$2'
fuera verdadera, pero no echo 0 | awk '$1=="000"'
.
Como otra peculiaridad, observe que, al menos en algunas implementaciones, $0
(el registro de entrada actual) pierde su propiedad mágica de "cadena numérica" si una asignación a un subcampo hace que se vuelva a calcular:
$ echo 0 | gawk '{$1=0} $0'
0
Esto no parece estar cubierto por el estándar, aunque coincide con el comportamiento de nawk/bwk en el que se basa el estándar awk (pero no con el de mawk).
Además, las implementaciones de awk pueden reconocer NAN
y INF
en INFINITY
la entrada como los números de punto flotante correspondientes, aunque el soporte para esto es irregular e inconsistente. Es posible que todavía te muerda, por ejemplo.
echo But his daughter named Nan | awk '$NF'
no imprimir nada en el awk de FreeBSD (bwk, original-awk).
Respuesta4
Porque $0 es elregistro completo(línea completa), $1, $2, soncampos(generalmente separados por espacios en blanco) en él.