糟糕,关于巨大的价值,它做得不好

时间:2019-12-02 15:01:09

标签: linux bash awk grep

我遇到了AWK的一些问题,基本上有一个名为ServerStatus的仓库,但是在某些服务器上却遇到了语法问题,下面是它得到的错误:

/usr/local/share/serverstatus-client.sh: line 121: let: SpeedRx=(1.10135e+10-1.10027e+10)/1: syntax error: invalid arithmetic operator (error token is ".10135e+10-1.10027e+10)/1")

我发现这是因为用于获取网络接口速度的grep命令上有一个awk,有时它完全被破坏了。

这个带有awk的grep组合输出的数字如3.172 + e09,让我们无法处理。

下面是有趣的代码:

# Network traffic
        NET=($(grep ":" /proc/net/dev | grep -v -e "lo" -e "tun" | awk '{a+=$2}{b+=$10}END{print a,b}'))
        NetRx="${NET[0]}"
        NetTx="${NET[1]}"
        if [ "$PREV_NetRx" == "" ]; then
                PREV_NetRx="$NetRx"
                PREV_NetTx="$NetTx"
        fi
        NetRx=$(echo $NetRx | awk '{ printf("%11.3f %11.3f\n", $1,$2) }')
        NetTx=$(echo $NetTx | awk '{ printf("%11.3f %11.3f\n", $1,$2) }')
        echo $NetRx
        let "SpeedRx=($NetRx-$PREV_NetRx)/$INTERVAL"
        let "SpeedTx=($NetTx-$PREV_NetTx)/$INTERVAL"
        PREV_NetRx="$NetRx"
        PREV_NetTx="$NetTx"

        echo -e "update {$Online \"uptime\": $Uptime, \"load\": $Load, \"memory_total\": $MemTotal, \"memory_used\": $MemUsed, \"swap_total\": $SwapTotal, \"swap_used\": $SwapUsed, \"hdd_total\": $HDDTotal, \"hdd_used\": $HDDUsed, \"cpu\": ${DIFF_USAGE}.0, \"network_rx\": $SpeedRx, \"network_tx\": $SpeedTx }"
done | $NETBIN $SERVER $PORT | while IFS= read -r -d $'\0' x; do
        if [ ! -f /tmp/fuckbash ]; then
                if grep -q "IPv6" <<< "$x"; then
                        echo "Connected." >&2
                        echo 4 > /tmp/fuckbash
                        exit 0
                elif grep -q "IPv4" <<< "$x"; then
                        echo "Connected." >&2
                        echo 6 > /tmp/fuckbash
                        exit 0
                fi
        fi
done

我尝试了一些解决方法,但是我真的不了解AWK的工作原理,有人可以帮我修复此命令吗?

以下是带有awk的grep的输出:

$~ grep ":" /proc/net/dev | grep -v -e "lo" -e "tun" | awk '{a+=$2}{b+=$10}END{print a,b}'
3.84806e+09 1068117604

这是不带awk的grep的输出:

$~ grep ":" /proc/net/dev | grep -v -e "lo" -e "tun"
  eth0: 1505583475 9395608    0 531466    0     0          0         0 200909161 2713202    0    0    0     0       0          0
  eth1: 2342591587 8367211    0    0    0     0          0         0 867289999 7634437    0    0    0     0       0          0

预先感谢您的帮助!


enter image description here

enter image description here

enter image description here

2 个答案:

答案 0 :(得分:3)

不是一个完整的答案(评论已经解决了所有问题),但想强调一些有关GNU awk默认行为的重要说明。

GNU awk程序非常适合使用整数。它可以表示最大2 ^ 1024(大约10 ^ 308)的整数,而不会损失精度。另一方面,bash对整数的支持基于标准的64个带符号的值,最大值为2 ^ 63(约5 *(10 ^ 18))。处理大数时,最好使用awk进行所有数学运算,并使用bash显示字符串化的数字。

在处理浮点数时,GNU awk使用标准的64浮点-约17位精度(52位)。大于此值的数字将使用上述高精度整数类型转换为整数。

有趣的是,awk是为数不多的脚本引擎之一,它将把大数从float提升为整数。大多数其他引擎会将大(整数)值提升为浮点数(精度较低),以将可以表示的范围从64位整数(2 ^ 63,大约5 * 10 ^ 18)增加到浮点允许的最大值。值(10 ^ 308)。

在Linux上,GNU awk通常是用GMP和MFPR库编译的,它们允许对浮点数和整数进行进一步的精度配置。

答案 1 :(得分:0)

@jhnc使用

进行了修复

grep ":" /proc/net/dev | grep -v -e "lo" -e "tun" | awk '{a+=$2}{b+=$10}END{printf "%f %f\n", a,b}'

一如既往,感谢大家的大力帮助!