condição awk de verdadeiro e falso


9

Me deparei que se usarmos awk 0 inputfile, ele não imprimirá nada, porque causa uma 0falsa condição.

Se usarmos awk 1 inputfile, ele imprimirá tudo como 1meio verdadeiro para cada linha que a awk interpreta.

Se usarmos awk any_string inputfile, ele não imprimirá nada, porque toda variável awk inicializada como zero é, portanto, falsa.

Mas se usarmos awk any_integer inputfile, ele se tornará verdadeiro e imprimirá cada linha do arquivo, posso saber qual é o motivo?

Eu não consigo encontrar isso foi explicado no manual GNUawk embora.


3
por any_integereu suponho que você número literal quer dizer como 7, 89etc .. Se assim for, a razão é qualquer número diferente de 0meios truecondição
Sundeep

Respostas:


13

Verdadeiro para o awk é uma sequência não vazia ou um número diferente de zero (com números inteiros decimais ou ponto flutuante e algumas implementações do awk hexadecimal ou octal também são suportadas). As coisas entre aspas duplas são seqüências de caracteres, números literais sem aspas são números, mas, para qualquer outra coisa, existem regras complexas para determinar se algo deve ser tratado como uma sequência ou um número. O awkmanual GNU tem um capítulo inteiro sobre isso .

Verdade:

  • awk '1' (número diferente de zero)
  • awk '1e8' (número diferente de zero)
  • awk '-0.01' (número diferente de zero)
  • awk '"foo"' (sequência não vazia)
  • awk '"0"' (sequência não vazia)
  • awk '0 ""' (concatenação produz uma string que aqui não está vazia)
  • echo 0 | awk '$1 ""' (o mesmo para um campo $ n)
  • awk 'substr("000", 1, 1)'(o resultado de substr()é sempre uma string)
  • echo '0foo' | awk '$0' ($ 0 é uma sequência não numérica, sendo considerada uma sequência (não vazia))

Falso:

  • awk '0' (Número 0)
  • awk '""' (cadeia vazia)
  • echo 0000e123 | awk '$1' ($ 1 é considerado um número se for uma sequência numérica em que está aqui e sendo 0)
  • echo ' 0 ' | awk '$0' (espaços à esquerda e à direita são ignorados para determinar se uma sequência é numérica).
  • awk '" 2foo" - 2' (uma sequência envolvida em uma expressão aritmética é convertida em um número com algo além do número ignorado)
  • awk 'unset_or_empty_variable' (cadeia vazia)
  • awk '"non-numerical-string" + 0'

YMMV:

  • awk '1e-500' (alguns reclamarão, outros o tratarão como 0)
  • awk '"0x1" + 0'(nem todas as implementações do awk suportam hexadecimais, naquelas que o fazem "0x1"são convertidas para 1, em outras, para 0. Algumas versões da especificação POSIX inadvertidamente exigiam implementações para oferecer suporte a esse número hexadecimal e ele foi retirado posteriormente. Ainda gawkreconhece esse número hexadecimal quando POSIXLY_CORRECTestá em o ambiente)
  • awk '010 - 8' (o mesmo (bem, não exatamente como o 010 é literal aqui, em vez de convertido de uma string) para octais)
  • awk '0x1 - 1'(em awkimplementações que não suportam números hexadecimais, 0x1é a concatenação 0e a x1variável que gera o "0"que é convertido em um número (0), se você subtrair, 1obtém -1qual é o número diferente de zero).

O que isso significa é que, se você deseja verificar se uma sequência de caracteres está vazia, não deve fazer:

awk '$ 1 {print $ 1, "não está vazio"}'

Mas

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

Caso contrário, não diria 0ou -0000E+00001234não está vazio.


Resposta impressionante e detalhada! Porém, uma pergunta: no exemplo final que você deu, tentei a sintaxe e a primeira funciona, onde pula o $ 1 que está vazio e apenas imprime essas linhas com $ 1 não vazio, porque se $ 1 for uma string vazia, será Falso e, portanto, não imprimindo a saída, não é?
sylye
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.