According to $ man gawk
, the strtonum()
function can convert a string into a number:
strtonum(str)
Examine str, and return its numeric value. If str begins with a leading 0, treat it as an octal number. If str begins with a leading 0x or 0X, treat it as a hexadecimal number. Oth‐ erwise, assume it is a decimal number.
And if the string begins with a leading 0
, the number is treated as octal, while if it begins with 0x
it's treated as hexadecimal.
I've run these commands to check my understanding of the function:
$ awk 'END { print strtonum("0123") }' <<<''
83
$ awk 'END { print strtonum("0x123") }' <<<''
291
The string "0123"
is correctly treated as containing an octal number and converted into the decimal number 83
.
Similarly, the string "0x123"
is correctly treated as containing an hexadecimal number and converted into the decimal number 291
.
Now, here's what happens if I run the same commands, but moving the numerical strings from the program text to the input data:
$ awk 'END { print strtonum($1) }' <<<'0123'
123
$ awk 'END { print strtonum($1) }' <<<'0x123'
291
I understand the second result which is identical as in the previous commands, but I don't understand the first one. Why does gawk now treat 0123
as a decimal number, even though it begins with a leading 0
which characterizes octal numbers?
I suspect it has something to do with the strnum attribute, because for some reason 1, gawk gives this attribute to 0123
but not to 0x123
:
$ awk 'END { print typeof($1) }' <<<'0123'
strnum
$ awk 'END { print typeof($1) }' <<<'0x123'
string
1 It may be due to a variation between awk implementations:
To clarify, only strings that are coming from a few sources (here quoting the POSIX spec): [...] are to be considered a numeric string if their value happens to be numerical (allowing leading and trailing blanks, with variations between implementations in support for hex, octal, inf, nan...).
I'm using gawk version 4.2.62
, and the output of $ awk -V
is:
GNU Awk 4.2.62, API: 2.0 (GNU MPFR 3.1.4, GNU MP 6.1.0)