De acordo com $ man gawk
, a strtonum()
função pode converter uma string em um número:
strtonum(str)
Examine str e retorne seu valor numérico. Se str começar com um 0 inicial, trate-o como um número octal. Se str começar com 0x ou 0X à esquerda, trate-o como um número hexadecimal. Caso contrário, assuma que é um número decimal.
E se a string começa com um 0
, o número é tratado como octal, enquanto se começa com 0x
é tratado como hexadecimal.
Eu executei estes comandos para verificar minha compreensão da função:
$ awk 'END { print strtonum("0123") }' <<<''
83
$ awk 'END { print strtonum("0x123") }' <<<''
291
A string "0123"
é tratada corretamente como contendo um número octal e convertida no número decimal 83
. Da mesma forma, a string "0x123"
é tratada corretamente como contendo um número hexadecimal e convertida no número decimal 291
.
Agora, aqui está o que acontece se eu executar os mesmos comandos, mas movendo as strings numéricas do texto do programa para os dados de entrada:
$ awk 'END { print strtonum($1) }' <<<'0123'
123
$ awk 'END { print strtonum($1) }' <<<'0x123'
291
Eu entendo o segundo resultado que é idêntico aos comandos anteriores, mas não entendo o primeiro. Por que o gawk agora trata 0123
como um número decimal, mesmo que comece com uma entrelinha 0
que caracteriza os números octais?
Suspeito que tenha algo a ver com o atributo strnum , porque por algum motivo 1 , gawk fornece esse atributo para , 0123
mas não para 0x123
:
$ awk 'END { print typeof($1) }' <<<'0123'
strnum
$ awk 'END { print typeof($1) }' <<<'0x123'
string
1 Pode ser devido a uma variação entre as implementações do awk:
Para esclarecer, apenas strings provenientes de algumas fontes (aqui citando a especificação POSIX): [...] devem ser consideradas uma string numérica se seu valor for numérico (permitindo espaços em branco à esquerda e à direita, com variações entre as implementações em suporte para hex, octal , inf, nan...).
Estou usando gawk version 4.2.62
e a saída de $ awk -V
é:
GNU Awk 4.2.62, API: 2.0 (GNU MPFR 3.1.4, GNU MP 6.1.0)
Isso está relacionado ao
strnum
tratamento generalizado na versão 4.2 do GAWK.Os valores de entrada que se parecem com números são tratados como
strnum
valores, representados internamente como tendo os tipos string e number. “0123” se qualifica como um número, então é tratado como umstrnum
.strtonum
é projetado para lidar com entradas de strings e números; ele procura por números primeiro e, quando encontra um número de entrada, retorna o número sem transformação:Assim, “0123” se torna o número 123 e
strtonum
o retorna diretamente.“0x123” não se parece com um número (pelas regras definidas no link fornecido acima), então é tratado como uma string e processado como você esperaria por
strtonum
.Um número é definido da seguinte forma em AWK :