2

我们使用简单的 curl 通过 API 获取指标。问题是,输出的参数数量是固定的,而不是它们在输出中的位置。

我们需要使用“简单”的正则表达式来做到这一点,因为该工具只接受这个。

/"name":"(.*)".*?"memory":(\d+).*?"consumer_utilisation":(\w+|\d+).*?"messages_unacknowledged":(\d+).*?"messages_ready":(\d+).*?"messages":(\d+)/s

它适用于:

{"name":"queue1","memory":89048,"consumer_utilisation":null,"messages_unacknowledged":0,"messages_ready":0,"messages":0}

但是,如果更改了输出顺序,则不再匹配:

{"name":"queue2","consumer_utilisation":null,"messages_unacknowledged":0,"messages_ready":0,"messages":0,"memory":21944}
{"name":"queue3","consumer_utilisation":null,"messages_unacknowledged":0,"messages_ready":0,"memory":21944,"messages":0}

我需要一个字符串的相对定义来匹配,因为我永远不知道它们会出现在哪个位置。它总共有 9 个不同的队列度量组。

4

1 回答 1

1

简单的选择是为每个键值对使用一个正则表达式,而不是一个大的正则表达式。

/"name":"((?:[^\\"]|\\.)*)"/
/"memory":(\d+)/

这个其他选项不是正则表达式,但可能就足够了。您可以在阅读结果之前简单地转换结果响应,而不是使用正则表达式。既然您说“我们正在使用简单的 curl”,我猜您是在谈论 Curl 命令行工具。您可以将结果通过管道传输到一个简单的 Perl 命令中。

perl -ne 'use JSON; use Text::CSV qw(csv); $hash = decode_json $_; csv (sep_char=> ";", out => *STDOUT, in => [[$hash->{name}, $hash->{memory}, $hash->{consumer_utilisation}, $hash->{messages_unacknowledged}, $hash->{messages_ready}, $hash->{messages}]]);'

这将保持顺序相同,从而更容易使用正则表达式来读取数据。

输入

{"name":"queue1","memory":89048,"consumer_utilisation":null,"messages_unacknowledged":0,"messages_ready":0,"messages":0}
{"name":"queue2","consumer_utilisation":null,"messages_unacknowledged":0,"messages_ready":0,"messages":0,"memory":21944}
{"name":"queue3","consumer_utilisation":null,"messages_unacknowledged":0,"messages_ready":0,"memory":21944,"messages":0}

输出

queue1;89048;;0;0;0
queue2;21944;;0;0;0
queue3;21944;;0;0;0

为此,您需要安装 Perl 和 JSON 和 Text::CSV 包。在我的系统上,它们存在于perllibjson-perllibtext-csv-perl

注意:我目前;用作分隔符。如果这包含在其中一个输出中,将用双引号括起来。"name":"que;ue1"=>"que;ue1";89048;;0;0;0如果该值同时包含 a;和 a ""则将通过在其前面放置另一个来进行转义。"name":"q\"ue;ue1"=>"q""ue;ue1";89048;;0;0;0

于 2019-03-25T14:26:51.243 回答