方便parsing单位后缀的数字?

假设您的数据具有可读格式的数量,例如du -h的输出,并且希望进一步操作这些数字。 比方说,你想通过greppipe道你的数据做一个数据的子集的总结。 你可以在许多你以前从未见过的系统上做这个特殊的工作,而且只需要很less的工具。 你想要所有的标准10 ^ n后缀后缀转换。

存在一个gnu-linux实用程序将后缀数字转换为stream水线中的实数? 你有写这样做的bash函数,或者一些perl可能很容易记住,而不是长度的正则expression式replace或几个sed步骤?

 38M /var/crazyface/courses/200909-90147 2.7M /var/crazyface/courses/200909-90157 1.1M /var/crazyface/courses/200909-90159 385M /var/crazyface/courses/200909-90161 1.3M /var/crazyface/courses/200909-90169 376M /var/crazyface/courses/200907-90171 8.0K /var/crazyface/courses/200907-90173 668K /var/crazyface/courses/200907-90175 564M /var/crazyface/courses/200907-90178 4.0K /var/crazyface/courses/200907-90179 

| grep 200907 | <amazing suffix conversion> | awk '{s+=$1} END {print s}'


相关参考文献:

  • 我怎么能按大小sorting
  • https://stackoverflow.com/questions/2557649/convert-memory-size-human-readable-into-actual-number-bytes-in-perl

根据我在你连接到的一个问题的答案:

 awk '{ ex = index("KMGTPEZY", substr($1, length($1))) val = substr($1, 0, length($1) - 1) prod = val * 10^(ex * 3) sum += prod } END {print sum}' 

另一种使用方法:

 sed 's/G/ * 1000 M/;s/M/ * 1000 K/;s/K/ * 1000/; s/$/ +\\/; $a0' | bc 

你可以使用Perl的正则expression式来做到这一点。 例如,

 $value = 0; if($line =~ /(\d+\.?\d*)(\D+)\s+/) { $amplifier = 1024 if ($2 eq 'K'); $amplifier = 1024 * 1024 if ($2 eq 'M'); $amplifier = 1024 * 1024 * 1024 if ($2 eq 'G'); $value = $1 * $amplifier; } 

这是一个简单的脚本。 你可以把它当作出发点。 希望它会帮助!

就个人而言,我不会首先使用-h标志。 “人类可读的”版本将数字舍去,当你转换回来时,需要重新舍入的数字变得更加准确。 (例如,2.7MiB是2831155.2字节,你用另一个字节的第八个字节做了什么?)

否则,你可以要求units将MiB / GiB / KiB转换为“B”,它将处理这个,但是你必须做一些类似的事情(假设你的输出是标签的,否则适当地cut

 {your output} | cut -f1 '-d{tab}' | xargs -L 1 -I {} units -1t {}iB B | awk '{s+=$1}END{printf "%d\n",s}' 
 VALUE=$1 for i in "g G m M k K"; do VALUE=${VALUE//[gG]/*1024m} VALUE=${VALUE//[mM]/*1024k} VALUE=${VALUE//[kK]/*1024} done [ ${VALUE//\*/} -gt 0 ] && echo VALUE=$((VALUE)) || echo "ERROR: size invalid, pls enter correct size"