%3F.png)
Quando awk recebe"0"como entrada, ele se comporta de maneira diferente em alguns casos. Código abaixo:
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}'
A saída com"0" (número zero):
[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 ~]#
A saída com"1" (número um):
[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 que há uma diferença quando eu uso var=0; echo $var | awk '$1=$1'
e var=1; echo $var | awk '$1=$1'
? Todos os números estão funcionando bem, exceto 0
.
Versões:
- GNU bash, versão 4.2.46
- GNU Awk 4.0.2
- coreutils-8.22-24.el7.x86_64
Responder1
Uma atribuição é uma expressão, portanto tem um valor – o mesmo valor atribuído. Assim, 'z = 1' é uma expressão com valor um.
Então
echo 0 | awk '$1=$1'
o padrão é avaliado como 0 (FALSO)echo 1 | awk '$1=$1'
o padrão é avaliado como 1 (TRUE) e a ação padrãoprint
é executada
Responder2
Não creio que seja uma questão de valor numérico: as conversões padrão cuidam disso (aqui, pelo menos).
O OP mostra quatro códigos awk diferentes, todas variações de: padrão {ação}
(a) $ 1 = $ 1
Isso reatribui $ 1 a si mesmo. Não é um teste booleano, é autônomo (efetivamente) e retorna o valor de $ 1. Se $1 for 0, o padrão éfalsoe o padrãoa ação de impressão é ignorada completamente. Se $1 for diferente de zero, oa entrada é impressa.
(b) { $1 = $1; imprimir; }
Isso reatribui $ 1 a si mesmo, também autônomo. Na ausência de um padrão, a ação é executada e a entrada ésempre impresso.
(c) $ 1 == $ 1
Essa é uma expressão booleana que ésempre verdade. 0 é 0 e 1 é 1 (e porco-da-terra é porco-da-terra). Na ausência de uma ação, a entrada ésempre impresso.
(d) { $1 == $1; imprimir; }
Não há padrão. A comparação é avaliada como um booleano verdadeiro que é descartado. A entrada ésempre impresso.
Responder3
As respostas existentes não conseguem explicar por que
echo 0 | awk '$0="0"'
echo 0 | awk '$0=substr($0,1)'
echo 0 | awk '$0=$0""'
todos serão impressos 0
, mas
echo 0 | awk '$0'
echo 000 | awk '$0'
não imprimirá nada, embora em todos os casos a expressão padrão seja avaliada como 0
.
Como é que 0
é verdadeiro num caso e falso no outro?
Isso porque as “variáveis de campo” (o resultado do $
operador) são tratadas como umcaso especial, e (se possível) são automaticamente convertidos paracadeias numéricas, que, se numericamente igual a 0
, será considerado falso quando usado em um contexto booleano:
Um valor de string deve ser considerado umsequência numéricase vier de um dos seguintes:
Variáveis de campo
Entrada da
getline()
função
FILENAME
ARGV
elementos da matriz
ENVIRON
elementos da matrizElementos da matriz criados pela
split()
funçãoUma atribuição de variável de linha de comando
Atribuição de variável de outra variável de string numérica
e [se parecer um número, leia toda a descriçãoaqui]
Por favor, leia também oRATIONALE
pelas razões pelas quais o conceito de strings numéricas e esse invólucro especial eram necessários, especialmente a parte sobre uma comparação como echo 0 000 | awk '$1==$2'
sendo verdadeira, mas não echo 0 | awk '$1=="000"'
.
Como outra peculiaridade, observe que, pelo menos em algumas implementações, $0
(o registro de entrada atual) perde sua propriedade mágica de "string numérica" se uma atribuição a um subcampo fizer com que ele seja recalculado:
$ echo 0 | gawk '{$1=0} $0'
0
Isso não parece ser coberto pelo padrão, embora corresponda ao comportamento de nawk/bwk no qual o padrão awk se baseia (mas não ao de mawk).
Além disso, as implementações do awk podem reconhecer NAN
, INF
e INFINITY
na entrada como os números de ponto flutuante correspondentes, embora o suporte para isso seja irregular e inconsistente. Você ainda pode ser mordido, por exemplo.
echo But his daughter named Nan | awk '$NF'
não imprimindo nada no awk do FreeBSD (bwk, original-awk).
Responder4
Porque $0 é oregistro inteiro(linha completa), $1, $2, sãoCampos(geralmente separados por espaços em branco) nele.