shell 从awk返回中提取数值

tzdcorbm  于 2022-11-16  发布在  Shell
关注(0)|答案(2)|浏览(137)

对于监控系统,我需要通过nrpe返回2个关于延迟的值到我的监控服务器。
这里是我正在处理的值(我将其放在一个文件中:test.txt):

{"status":"success","data":{"resultType":"vector","result":[{"metric":{"project_site":"AUB"},"value":[1575277537.052,"0.3889104875437488"]},{"metric":{"project_site":"VDR"},"value":[1575277537.052,"0.2267407994117705"]}]}}

我需要提取0.38891048754374880.2267407994117705
我用这个:

for i in $(""cat test.txt | awk -F ',' '{print $5 $NF}' | grep -o '[0.0001-9999.9]\+'""); do echo $i; done

我不确定这是不是最好的方法,特别是我必须补充一点:每行之前的第1行为“AUB”,第2行为“VDR”。例如:

AUB : 0.3889104875437488 seconds
VDR : 0.2267407994117705 seconds
pieyvz9o

pieyvz9o1#

使用jq解析JSON,例如:

$ jq -r '.data.result[] | "\(.metric.project_site) : \(.value[1]) seconds"' file
AUB : 0.3889104875437488 seconds
VDR : 0.2267407994117705 seconds
8gsdolmq

8gsdolmq2#

我已经通过@oguzismail对答案投了赞成票,如果可行的话,我会重复他们的建议,使用jq代替。
如果您的输入不是有效的JSON,那么您的方法有几个问题,其中几个问题更多地与效率和常见实践有关,而不是完全错误。
1.您的正则表达式错误。请参阅下面的内容。
1.避免useless cat .
1.如果你使用的是Awk,你就不需要grep

  1. Quote your variable.
    1.只有在这种情况下,您才希望完全删除无用的echo。捕获标准输出以便可以将其echo到标准输出只是浪费过程(除非您特别希望打破引用,作为前一项的特例;但这里不是这种情况)。
    1.我们不清楚空字符串""的目的是什么,在shell删除引号后,""cat就变成了cat
    更详细地说,[0.0001-9999.9]匹配单个字符0.0(哦,我们已经提到过了,不是吗?)或0(同上)或者在199之间(等等)。简而言之,grep根本不是搜索数字范围的正确工具;幸运是,Awk也可以轻松地做到这一点。
    因此,这里尝试重构以消除这些问题。
awk -F ',' '{ split("5:" NF, a, ":"); split("AUB:VDR", l, ":")
  for (i=1; i<=2; i++) {
    n = $a[i]; gsub(/[]}"]+/, "", n);
    if (n >= 0.0001 && n <= 9999.9)
      print l[i] ": " n " seconds"} }' test.txt

这非常脆弱,因为它将字符串的位置硬编码在JSON数据的表层结构中(而不是?),而这些位置可能会在没有警告的情况下发生变化。
split是一个将数字5和NF放入数组a中的技巧。我们为相应的标签创建了第二个具有相同长度的数组。然后循环第一个数组,并使用数字作为当前记录字段的索引。我们去掉所有引号和括号,然后对提取的字段进行数字比较。最后,我们将另一个数组中的相应标签添加到打印文本的前面。

相关问题