使用正则表达式仅提取带宽值

时间:2016-11-23 15:28:07

标签: python regex awk sed

如何从以下转储中提取带宽值

------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 85.3 KByte (default)
------------------------------------------------------------
[  4] local 192.168.1.1 port 5001 connected with 192.168.1.2 port 51725
[ ID] Interval       Transfer     Bandwidth
[  4]  0.0-10.0 sec  10.7 GBytes  9.17 Gbits/sec
[  5] local 192.168.1.1 port 5001 connected with 192.168.1.2 port 51726
[  5]  0.0-10.0 sec  10.7 GBytes  9.17 Gbits/sec
[  4] local 192.168.1.1 port 5001 connected with 192.168.1.2 port 51727
[  4]  0.0-10.0 sec  10.6 GBytes  9.10 Gbits/sec
[  5] local 192.168.1.1 port 5001 connected with 192.168.1.2 port 51728
[  5]  0.0-10.0 sec  10.4 GBytes  8.91 Gbits/sec
[  4] local 192.168.1.1 port 5001 connected with 192.168.1.2 port 51729
[  4]  0.0-10.0 sec  10.8 GBytes  9.23 Gbits/sec
[  5] local 192.168.1.1 port 5001 connected with 192.168.1.2 port 51730
[  5]  0.0-10.0 sec  10.7 GBytes  9.22 Gbits/sec
[  4] local 192.168.1.1 port 5001 connected with 192.168.1.2 port 51731
[  4]  0.0-10.0 sec  10.7 GBytes  9.23 Gbits/sec
[  5] local 192.168.1.1 port 5001 connected with 192.168.1.2 port 51732
[  5]  0.0-10.0 sec  10.7 GBytes  9.16 Gbits/sec
[  4] local 192.168.1.1 port 5001 connected with 192.168.1.2 port 51733
[  4]  0.0-10.0 sec  10.6 GBytes  9.13 Gbits/sec
[  5] local 192.168.1.1 port 5001 connected with 192.168.1.2 port 51734
[  5]  0.0-10.0 sec  10.5 GBytes  9.02 Gbits/sec
[  4] local 192.168.1.1 port 5001 connected with 192.168.1.2 port 51735
[  4]  0.0-10.0 sec  10.3 GBytes  8.85 Gbits/sec

我的预期输出是

9.17,9.17,9.10,8.91,9.23,9.22,9.23,9.16,9.13,9.02,8.95

我只是尝试用python做这个,但我想知道其他更快更简单的方法来提取这个细节。

2 个答案:

答案 0 :(得分:5)

awk将是一个很好的候选人

$ awk -v ORS="," '$8 == "Gbits/sec"{print $7}' file
9.17,9.17,9.10,8.91,9.23,9.22,9.23,9.16,9.13,9.02,8.85,

它的作用是什么?

  • -v ORS=","将输出记录分隔符设置为,。这会使每个print,分隔。

  • '$8 == "Gbits/sec"检查第8列是否与Gbits/sec匹配,如果是,则打印7字段,即带宽

如果您担心上次,,我们可以写,

$ awk -v ORS="" '$8 == "Gbits/sec"{print sep$7; sep=","} END{print "\n"}' file

修改

正如@ mklement0指出的那样,如果线路的起点像[111]那样填满,则可能会失败。在这种情况下,我们可以重写为,

$ awk -v ORS="" '$NF == "Gbits/sec"{print sep$(NF-1); sep=","} END{print "\n"}' file

此处,NF是每行中的字段/列数。因此$NF将是最后一个字段,而$(NF-1)将是最后一列。

答案 1 :(得分:2)

如果grep选项可用,则pcre

$ grep -oP '[0-9.]+(?=\s*Gbits)' ip.txt | paste -sd,
9.17,9.17,9.10,8.91,9.23,9.22,9.23,9.16,9.13,9.02,8.85
  • [0-9.]+要提取的数字
  • (?=\s*Gbits)仅当后跟可选空格和文本Gbits
  • 然后使用paste命令将输出合并为单行,,作为分隔符


来自man grepman paste

  

grep,egrep,fgrep,rgrep - 打印匹配模式的行

     

-o, - 仅匹配         仅打印匹配行的匹配(非空)部分,每个此类部分位于单独的输出行上。

     

-P, - pel-regexp         将模式解释为Perl兼容的正则表达式(PCRE)。这是高度实验性的,grep -P可能         警告未实现的功能。

     

粘贴 - 合并文件行

     

-s, - serial         一次粘贴一个文件而不是并行粘贴

     

-d, - delimiters = LIST         重用LIST中的字符而不是TAB