删除最后一个字符,并使用awk将值乘以数字

时间:2015-01-07 06:54:20

标签: bash awk

我正在使用dstat工具来获取eth0接口的网络使用情况。 dstat给出如下​​输出:

----total-cpu-usage---- -dsk/total- --net/eth0- ---paging-- ---system--
usr sys idl wai hiq siq| read  writ| recv  send|  in   out | int   csw
  3   2  95   1   0   0|4035B  143k|   0     0 |   0     0 |1539  2511
  3   3  94   0   0   0|   0    24k|3924B 7549B|   0     0 |1821  2851
  3   3  94   0   0   0|   0    84k|3766B 2648B|   0     0 |1787  2895 

我可以在单独的文件中获取 - net / eth0 - 的值。但我想使用 3924B 值并删除最后一个字符 B / K / M 。如果 K ,则将剩余数字乘以1024,如果 M 使用awk,则乘以1024 * 1024。 例如,如果它是37K:我想要37888(37 * 1024)。

到目前为止,我可以使用以下代码获取另一个文件中的值:

dstat $Intrfc $Intrvl $repNo | sed '1,2d' | awk -F '|' '{print $3 }' | awk '{print $1 "," $2}' | sed "s/^/`date +%m:%d:%Y:%H:%M:%S`,/" >> $outFile

3 个答案:

答案 0 :(得分:1)

您只需在0中添加awk即可摆脱B

dstat $Intrfc $Intrvl $repNo awk -F\| 'NR>2 {split($3,a," ");print a[1]+0","a[2]+0}'
0,0
3924,7549
3766,2648

用数学:

awk -F\| 'NR>2 {split($3,a," ");a[1]*=(a[1]~/K$/?1024:1);a[1]*=(a[1]~/M$/?1048576:1);a[2]*=(a[2]~/K$/?1024:1);a[2]*=(a[2]~/M$/?1048576:1);print a[1]","a[2]}'

答案 1 :(得分:1)

这是一种方法。根据要求,它会将K个数字乘以1024,将M个数字乘以1048576.它需要GNU awk

dstat $Intrfc $Intrvl $repNo | awk -F '[| ]+' -v d=$(date +%m:%d:%Y:%H:%M:%S) -v OFS=, 'function cvt(x){return lshift(x, 10*(x~/K/)+20*(x~/M/))} NR>2 {print d,cvt($10),cvt($11)}'

解释

  • -F '[| \t]+'

这会将字段分隔符设置为空格和/或竖线的任意组合。使用此字段分隔符,net / eth0 recv为字段10,writ为字段11。

  • -v d=$(date +%m:%d:%Y:%H:%M:%S)

    这会创建一个awk变量d,并将其分配给date命令的输出。

  • -v OFS=,

    这会将输出字段分隔符设置为逗号。

  • function cvt(x){return lshift(x, 10*(x~/K/)+20*(x~/M/))}

    这会创建一个转换函数,如果数字以K结尾,则乘以1024,如果数字以M结尾,则乘以1048576。

    乘法是通过左移K或M的数字10或20位来执行的。

    请注意,此功能使用awk的松散输入。

  • NR>2 {print d,cvt($10),cvt($11)}

    打印输出。 NR是行号。跳过前两行,对于所有后面的行(NR>2),将打印日期,然后是转换后的列10和转换后的列11.

答案 2 :(得分:1)

首先,不要在管道蛇中使用多个awksed。它可以一步一awk完成。这是一个可能的解决方案:

awk -F"[ \t|]+" -v dt=$(date +%m:%d:%Y:%H:%M:%S) '
function num(n) {
  if (n ~ "B$") n=substr(n,1,length(n)-1);
  else if (n ~ "K$") n=substr(n,1,length(n)-1)*1024;
  else if (n ~ "M$") n=substr(n,1,length(n)-1)*1024*1024;
  return n;
}
NR>2{print num($10)","num($11)","dt}
' <<TXT
----total-cpu-usage---- -dsk/total- --net/eth0- ---paging-- ---system--
usr sys idl wai hiq siq| read  writ| recv  send|  in   out | int   csw
  3   2  95   1   0   0|4035B  143k|   0     0 |   0     0 |1539  2511
  3   3  94   0   0   0|   0    24k|3924K 7549B|   0     0 |1821  2851
  3   3  94   0   0   0|   0    84k|3766M 2648B|   0     0 |1787  2895 
TXT

输出:

0,0,01:07:2015:09:32:24
4018176,7549,01:07:2015:09:32:24
3.94894e+09,2648,01:07:2015:09:32:24

更短的版本,更大的数字输出更好(我借用了John1024的乘法思想):

awk -F"[ \t|]+" -v dt=$(date +%m:%d:%Y:%H:%M:%S) '
function num(n) {
  m="";
  if (n~"[^0-9]$") {m=substr(n,length(n),1);n=substr(n,1,length(n)-1);}
  return n * 2**(m=="K"?10:m=="M"?20:0);
}
NR>2{printf("%d,%d,%s\n", num($10),num($11),dt)}
'

输出:

0,0,01:07:2015:09:30:27
4018176,7549,01:07:2015:09:30:27
3948937216,2648,01:07:2015:09:30:27

在我使用here-doc而不是管道dstat的示例中,因为我没有安装dstat。

我希望这可以提供帮助。