在 bash 中处理超出范围的整数

Sha*_*dra 2 bash awk biginteger

我已将 vmstat 数据收集到一个文件中。它提供了有关 free、buffer 和 cache 的详细信息。由于我对查找内存使用情况感兴趣,因此我应该对 vmstat 输出的每一行进行以下计算 -- USED=TOTAL - (FREE+BUFFER+CACHE) 其中 TOTAL 是总 RAM 内存,USED 是瞬时内存值。总内存 = 4042928 (4 GB)

我的代码在这里

grep -v procs $1 | grep -v free | awk '{USED=4042928-$4-$5-$6;print $USED}' > test.dat
awk: program limit exceeded: maximum number of fields size=32767
        FILENAME="-" FNR=1 NR=1
Run Code Online (Sandbox Code Playgroud)

pax*_*blo 5

您不应该$USED一开始就打印,其中的变量awkUSED

pax> vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 0  0      0 1402804 258392 2159316    0    0    54    79  197  479  1  2 93  3

pax> vmstat | egrep -v 'procs|free' | awk '{USED=4042928-$4-$5-$6;print USED}'
222780
Run Code Online (Sandbox Code Playgroud)

在您的情况下最有可能发生的情况是您使用的awk限制是每条记录大约 32000 个字段。

因为您的字段456分别是251726648520(来自您的评论之一),所以您的USED值变为4042928-25172-664-85204008572

如果您尝试打印USED,这就是您会得到的结果,但是,因为您尝试打印$USED,它认为您想要$4008572(字段号 4008572),这只是超出了 32000 范围。

有趣的是,如果你有更多的可用内存,你不会收到错误,但你仍然会得到一个错误的值:-)

顺便说一句,gawk没有这个限制,它只是打印一个空字段(例如,请参见此处的第 11.9 节)。