从一行中提取多个浮点数

我想从下面的行中提取timeTaken值:

<some other log data> Exception, Curl1-Time: 0.258315s. Curl2-Time: 3.9092588424683s Exiting. 

我正在用grepawk使用以下命令:

 grep -Po "Exception, Curl1-Time: \K(\d+.\d*)s. Curl2-Time: (\d+.\d+)" app.log | awk '{print $1 + $3}' 

这输出: 4.167565

  1. 这可以做更聪明的方式,也许使用sed或任何其他bash工具。
  2. 可以忽略尾随“s”。 在添加结果的时间价值是正确的。

您已经使用PCRE。 为什么不使用Perl本身?

 perl -lne 'print $1 + $2 if /Exception, Curl1-Time: ([\d.]+)s\. Curl2-Time: ([\d.]+)/ ' < input 

如果你有GNU的grep ,那么你可以执行:

 var="<some other log data> Exception, Curl1-Time: 0.258315s. Curl2-Time: 3.9092588424683s Exiting." grep -Eo '[[:digit:]]+\.[[:digit:]]+s?' <<< "$var" 

或者你可以使用awk并保持POSIX :

 var="<some other log data> Exception, Curl1-Time: 0.258315s. Curl2-Time: 3.9092588424683s Exiting." awk '{ while (match($0, /[[:digit:]]+\.[[:digit:]]+s?/)) { print substr($0, RSTART, RLENGTH); $0 = substr($0, RSTART + RLENGTH) } }' <<< "$var" 

正如你所看到的,这两个命令都使用正则表达式[[:digit:]]+\.[[:digit:]]+s? 匹配一个或多个数字,一个点,一个或多个数字和一个可选 “s”的模式

GNU的grep使用-o选项来提取匹配的正则表达式模式。

awk版本使用其matchsubstr函数来匹配和提取相关数据。 在正则表达式匹配后, RSTARTRLENGTH被设置,我们可以使用它们来计算substr开始结束位置。

RLENGTHmatch函数匹配的子字符串的长度。

RSTART是由match函数匹配的子字符串的起始索引。

请参见字符串操作的内置函数部分

 sed 's/.*Curl1-Time: \([0-9]\.[0-9]*\)s.*\([0-9]\.[0-9]*\)s.*$/\1 \2/p' filename | awk '{print ($1+$2);}' 
  • 正则表达式模式匹配“ 。Curl1-Time:([0-9]。[0-9] )s。 ([0-9]。[0-9] )s。* $”—>是匹配正则表达式的数字。
  • 整行被替换为两个匹配的模式。 即sed的输出将是两个数字,它们之间有空格。 例如1234 34567
  • awk使用默认空格分隔符解析sed输出,并将它们汇总并打印结果。