json - jq- 循环中的参考当前位置
问题描述
我有一个名为的日志文件log.json
,其格式如下:
{"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
读取两个文件的函数编写一个函数,并且每当它找到与 a msg
inlog.json
匹配的 a msg
in 时messages.json
,打印out
in 相应行中的值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 时打印 every (这是有道理的。$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
,然后打印出来。有没有办法让我做到这一点(或者我可以使用完全独立的方法)?
解决方案
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
推荐阅读
- python-3.x - 在 Python 中对数据框进行部分重采样
- http - 在 Flask 请求中更改标头的最佳做法是什么?
- vim - Vim 高级替换
- javafx - JavaFX:调整画布大小无法正常工作
- python-3.x - 使用 PyPDF2 解压缩 PDF FlateDecode 过滤器注释
- java - 带有斜杠的 Spring Boot Json 反序列化
- php - 显示 PHP 选择连接的 LDAP 服务器
- reactjs - Flatlist scrollToIndex 与 Hooks useRef
- angular - 如何使用 WSL 在 Dropbox 目录中开发 Angular 项目?
- python - 检查Linux程序是否停止运行