awk不是四舍五入的,你用final final()命令去掉最后一位数字。看:
$ a=`echo 9.1200 | awk '{ if ($0 ~ /\./){ sub("0*$","",$0); sub ("\\.$","",$0);} print}'
$ echo $a
9.1
$ a=`echo 9.1200 | awk '{ if ($0 ~ /\./){ sub("0*$","",$0); sub ("[.]$","",$0);} print}'`
$ echo $a
9.12
你的命令行有几个错误。
- 子()需要一个RE,因为它的第一个参数,因此概要使用一个明确的RE时是不
sub(/RE/,...)
sub("RE",...)
(谷歌AWK解析字符串文字)。
- sub()的第三个参数默认为$ 0,所以不需要明确加上 它。
- 你不需要多次调用sub()去除 字符串的末尾,只是一个简单的ERE。
- awk脚本为
<condition> { <action> }
块,所以不要将 条件置于操作块内。
- 将字符串转换为数字的自然方法就是使用 数字运算符,而不是尝试操纵字符串以像数字一样查找 。
- 不要使用弃用的反引号来调用命令,因为除其他外,他们解释反斜杠,所以awk命令看到的是
sub("\.$"..
而不是您想要的sub("\\.$"..
。
- 总是给shell变量
这里有一个有效的语法做你尝试使用字符串操作做什么:
$ a=$(echo 9.1200 | awk '/\./{ gsub(/\.0*$/,""); print}')
$ echo "$a"
9.12
但这是简单的:
$ a=$(echo 9.1200 | awk '/\./{ print $0+0 }')
$ echo "$a"
9.12
和如果输入数据始终为数字,则根本不需要测试/\./
:
$ a=$(echo 9.1200 | awk '{print $0+0}')
$ echo "$a"
9.12
你遇到的主要问题是使用反斜杠,所以让我稍微解决一下。当你写的包括RE元字符,如.
你想当作文字字符的RE你有2种选择:
/\./
或
/[.]/
让我们假设你决定使用前者。一切都很好,直到你决定使用字符串分隔符而不是RE分隔符。字符串文字解释了两次,一次是当脚本再次读取并执行时会这样逃跑元字符,你需要转义两次的RE,例如:
"\\."
现在让我们假设你决定调用你的awk脚本将输出保存在shell变量中。你有两个选择:
var=`awk '...'`
或:
var=$(awk '...')
当您使用后者是没有问题的,但是当你使用前者,那`...`本身语法解释对反斜线的单反斜线,所以你需要添加另一个反斜杠逃脱.
,即:
var=`awk '... "\\\." ...'`
显然转义失控。
所以 - 为了避免反斜线地狱,使用的RE时使用RE定界符/.../
尽可能*而不是字符串分隔符"..."
,当执行shell脚本使用$(...)
,而不是旧风格的`...`。 *当您需要字符串分隔符时,您需要将文字RE段与变量连接起来或在变量中保存一个RE,例如, var="a.b"; sub(var,"")
或sub(var".*","")
。
期望的行为是什么? – 2014-08-29 10:29:47
我想要的输出是9.12 – Marjer 2014-08-29 10:30:18
脚本是否应该删除多余的额外零?你能提供一些不同的输入和相应的期望输出吗? – 2014-08-29 10:30:55