我有一个简单的问题,这对我来说已经消耗了一天的大部分时间。简而言之,我试图使用awk
从字符串中删除前导零。 然而,在大家将此标记为重复之前,问题不在于如何删除前导零(这只是我想要实现的结果)。另外,这是特别关于变量的读取;我很清楚输出操作的格式字符串。
我的问题是:每当我尝试将给定变量强制转换为整数时,awk
正在读取前导零并将输入数视为八进制字符串。我有一些简单的例子来演示以下行为:
$ echo "0012" | awk '{$1=$1+0}1'
10
$ echo "0012" | awk '{$1=+$1}1'
10
$ echo "0011" | awk '{print ($1 + 0)}'
9
$ echo "0000" | awk '{$1=$1+0}1'
0
现在,我已经看到许多解决方案提供了各种sed
命令来“预处理”并删除前导零。不幸的是,对我来说完全有效的输入是0000
,基于字符串的解决方案会折叠为空字符串。
简而言之,如何强制awk
将其读取的变量视为十进制,而不管前导零?
How to delete all characters but the last
strip leading zeros in awk program
Removing Leading Zeros within awk file
我在原帖中忘记提及的事情:我正在尝试将0000
合并为一个0
。此外,我理想的解决方案是awk
- 只是因为我的环境很薄(在嵌入式Linux和桌面操作系统之间)。有问题的awk
由BusyBox 1.18.1提供,但其他一切应该非常接近现代桌面版Linux。
答案 0 :(得分:5)
使用busybox
调用awk
,似乎可以执行以下操作:
$ printf '%s\n' 0000 0011 0012 |
busybox awk '{print ($1".")+0}'
0
11
12
Posix要求awk
使用等效的strtod
将数据值转换为数字,而我能找到的所有awk
实现都会这样做,busybox awk
除外。 (Busybox
当然并不声称与Posix兼容,但它有时会在这种情况下具有侵略性的不兼容性。)所以{print $1 + 0}
应该可以正常工作,但它并不适用于busybox awk
的情况,它将允许输入数据中的十六进制或八进制整数。
在数字上附加.
会强制将整数视为浮点数,并且对实际浮点数没有影响,因为strtod
在遇到可以&的字符时才会停止#39;被解码为数字的一部分。当然,如果该字段不是完全数字,它也将无效,因此如果您希望将0017a
之类的字段转换为17a
(或甚至17
),解决方案不适合你。
作为旁注,awk
中字符串连接的优先级低于加法的优先级(并且高于比较运算符),因此括号实际上是必需的; awk
会将print $1""+0
解析为print $1(""+0)
,它会将{0}附加到字符串值$1
。 GNU awk
手册表明,除了琐碎的表达式之外,你应该总是将连接加上括号,这对我来说是个好建议。
此外,当我尝试对busybox awk
的数字转换算法进行逆向工程时,我发现它将012e3
视为整数10而不是12000. {{1}但是,12e3
转换为12000。如果不是特殊的话,012.e3
就没有任何意义。