jq-循环中的参考当前位置

时间:2018-04-27 16:36:42

标签: json dictionary jq

我有一个名为{"msg": "Service starting up!"} {"msg": "Running a job!"} {"msg": "Error detected!"} 的日志文件,其格式如下:

messages.json

另一个名为{"msg": "Service starting up!", "out": "The service has started"} {"msg": "Error detected!", "out": "Uh oh, there was an error!"} {"msg": "Service stopped", "out": "The service has stopped"} 的文件,如下所示:

jq

我尝试使用msg编写一个函数来读取这两个文件,并且每当它在log.json中找到与msg匹配的messages.jsonout,在messages.json的相应行中打印"The service has started" "Uh oh, there was an error!" 的值。因此,在这种情况下,我希望将此作为输出:

jq --argfile a log.json --argfile b messages.json -n 'if ($a[].msg == $b[].msg) then $b[].out else empty end'

我能够达到的最接近的目标如下:

out

这成功地执行了我希望做的所有比较。但是,不是打印我正在查找的特定out,而是只要if语句返回true,它就会打印每个$b[].out(这是有道理的。"The service has started" "Uh oh, there was an error!" "The service has stopped" "The service has started" "Uh oh, there was an error!" "The service has stopped" 从未重新定义,并询问他们每个人)。所以,这句话输出:

$b[current_index].out

所以在这一点上,我需要一些方法来询问auth: { twitter: { consumer_key: "qweREbUdsfsdfsdfsdfsd4wIg9EX", // REQUIRED consumer_secret: "AZrUDjnEVUsdfsdfsdfsdfsdfsdfsdfxcpxBtM0X3" // REQUIRED }, facebook: { appIds: "8489456465" } } ,然后打印出来。有没有办法让我这样做(或者我可以使用完全独立的方法)?

1 个答案:

答案 0 :(得分:1)

messages.json有效地定义了一个字典,所以让我们首先创建一个我们可以轻松查找的JSON字典。这可以使用INDEX / 2方便地完成(如果你的jq没有它)定义如下:

def INDEX(stream; idx_expr):
  reduce stream as $row ({};
    .[$row|idx_expr|
      if type != "string" then tojson
      else .
      end] |= $row);

首先解决方案现在很简单:

INDEX($messages[]; .msg) as $dict
| inputs
| $dict[.msg]
| .out 

假设这是在program.jq中,适当的调用将如下(特别注意-n选项):

jq -n --slurpfile messages messages.json -f program.jq log.json

如果日志文件中的null不在字典中,则上述内容将打印.msg。要过滤掉这些空值,您可以(例如)将select(.)添加到管道中。

另一种可能性是使用原始.msg,如此变体:

INDEX($messages[]; .msg) as $dict
| inputs
| . as $in
| $dict[.msg]
| .out // $in.msg