filter - 如何合并由逗号分隔的过滤器生成的 jq JSON 对象
问题描述
我正在尝试使用 jq 将一些命令行标志转换为 JSON 等价物。
标志看起来像这样,其想法是将(可选)f标志转换为JSON“foo”字段,将(可选)b标志转换为JSON“bar”字段:
{
"flags": [
"f1",
"b2",
"f3b4",
"b6f5"
]
}
获取 foo 字段很容易:
.flags[] | match("f([0-9][0-9]*)") | .captures[0].string | tonumber | { "foo": . }
对于 bar 字段也是如此(请说明是否有更好的方法来使用 jq 执行此操作):
.flags[] | match("b([0-9][0-9]*)") | .captures[0].string | tonumber | { "bar": . }
如何将这两个过滤器的输出合并在一起,以便每个输入标志行都映射到一个 JSON 对象,其中没有/一个/两个可选字段?
两个相关的机制是 jq 的逗号运算符(在多个过滤器之间共享单个流)和 jq 的 + 运算符(将对象合并为单个对象)。应用逗号运算符很简单:
.flags[] | (match("f([0-9][0-9]*)") | .captures[0].string | tonumber | { "foo": . }), (match("b([0-9][0-9]*)") | .captures[0].string | tonumber | { "bar": . })
但是,这会为每个匹配生成一个单独的对象:
{
"foo": 1
}
{
"bar": 2
}
{
"foo": 3
}
{
"bar": 4
}
{
"foo": 5
}
{
"bar": 6
}
所以这里的具体问题是如何使用 + 运算符将这两个对象连接在一起。我试图在这里得到的最终输出是 foo 和 bar 字段一起位于同一个对象中的位置:
{
"foo": 1
}
{
"bar": 2
}
{
"foo": 3,
"bar": 4
}
{
"foo": 5,
"bar": 6
}
用 jq 实现这一目标的最佳方法是什么?
解决方案
捕获功能似乎适合您的任务。
来自手册:capture(regex; flags)
“在 JSON 对象中收集命名的捕获,每个捕获的名称作为键,匹配的字符串作为对应的值。”
jq '.flags[]
| capture("(?<foo>^f\\d+$)"),
capture("(?<bar>^b\\d+$)"),
capture("(?<foo>f\\d+)(?<bar>b\\d+)"),
capture("(?<bar>b\\d+)(?<foo>f\\d+)")
| .[] |= ( sub("\\D"; "") | tonumber )'
捕获线创建这些对象:
{
"foo": "f1"
}
{
"bar": "b2"
}
{
"foo": "f3",
"bar": "b4"
}
{
"bar": "b6",
"foo": "f5"
}
最后一行通过删除非数字并将结果转换为数字来更新这些对象中的值。
推荐阅读
- python - websocket._exceptions.WebSocketBadStatusException:握手状态 404 未找到
- sql - 如何删除 SQL Developer 列值中隐藏的双引号
- ksh - 为什么 IFS 会影响 subshell 变量?
- reactjs - 浏览器如何将 Reactstrap 组件解析为 html 标签?
- c# - 添加多个 css 类 @Html.LabelFor
- python-3.x - 一次过滤和添加新列时出现值错误
- arrays - 如何修复此代码,从服务中获取数据并使用 Reactive Form 将其发送到我的表单?
- maven - 将命令的输出放入变量 GoCD
- haskell - 我需要 HashSet 还是 Set?
- python - 尝试纠正此错误:IndexError: index 0 is out of bounds for axis 0 with size 0