使用 jq 选择和过滤 cloudflare pagerules
selecting and filtering cloudflare pagerules with jq
我试图找到从 Cloudflare 中过滤掉一些 pagerules 数据的最佳方法,虽然我有一个解决方案,但我正在研究它有多丑陋,并认为“必须有一个更简单的方法这样做。"
我特别询问使用 jq 实现以下目标的更好方法。我知道我可以使用一些编程库来完成同样的任务,但这个问题的重点是更好地理解 jq 是如何工作的。
假设我有一长串 CloudFlare pagerules 记录,这里有一些条目作为最小示例:
{
"example.org": [
{
"id": "341",
"targets": [
{
"target": "url",
"constraint": {
"operator": "matches",
"value": "http://ng.example.org/*"
}
}
],
"actions": [
{
"id": "always_use_https"
}
],
"priority": 12,
"status": "active",
"created_on": "2017-11-29T18:07:36.000000Z",
"modified_on": "2020-09-02T16:09:03.000000Z"
},
{
"id": "406",
"targets": [
{
"target": "url",
"constraint": {
"operator": "matches",
"value": "http://nz.example.org/*"
}
}
],
"actions": [
{
"id": "always_use_https"
}
],
"priority": 9,
"status": "active",
"created_on": "2017-11-29T18:07:55.000000Z",
"modified_on": "2020-09-02T16:09:03.000000Z"
},
{
"id": "427",
"targets": [
{
"target": "url",
"constraint": {
"operator": "matches",
"value": "nz.example.org/*"
}
}
],
"actions": [
{
"id": "ssl",
"value": "flexible"
}
],
"priority": 8,
"status": "active",
"created_on": "2017-11-29T18:08:00.000000Z",
"modified_on": "2020-09-02T16:09:03.000000Z"
}
]
}
我想要做的是提取嵌套在 constraint.value 字段中用于 always_use_https 操作的 url。目标是提取值并将它们 return 作为 json 数组。我想到的是:
jq '[
[
[
[
.[] | .[] | select(.actions[].id | contains("always_use_https"))
] | .[].targets[] | select(.target | contains("url"))
] | .[] | .constraint | select(.operator | contains("matches"))
] | .[].value
]'
针对我们的例子,这会产生:
[
"http://ng.example.org/*",
"http://nz.example.org/*"
]
在 jq 中有没有更简洁的方法来实现这个?
这会根据我理解的标准产生预期的输出:
jq '.["example.org"]
| map(select( any(.actions[]; .id == "always_use_https"))
| .targets[]
| select(.target == "url")
| .constraint.value )
' cloudfare.json
我试图找到从 Cloudflare 中过滤掉一些 pagerules 数据的最佳方法,虽然我有一个解决方案,但我正在研究它有多丑陋,并认为“必须有一个更简单的方法这样做。"
我特别询问使用 jq 实现以下目标的更好方法。我知道我可以使用一些编程库来完成同样的任务,但这个问题的重点是更好地理解 jq 是如何工作的。
假设我有一长串 CloudFlare pagerules 记录,这里有一些条目作为最小示例:
{
"example.org": [
{
"id": "341",
"targets": [
{
"target": "url",
"constraint": {
"operator": "matches",
"value": "http://ng.example.org/*"
}
}
],
"actions": [
{
"id": "always_use_https"
}
],
"priority": 12,
"status": "active",
"created_on": "2017-11-29T18:07:36.000000Z",
"modified_on": "2020-09-02T16:09:03.000000Z"
},
{
"id": "406",
"targets": [
{
"target": "url",
"constraint": {
"operator": "matches",
"value": "http://nz.example.org/*"
}
}
],
"actions": [
{
"id": "always_use_https"
}
],
"priority": 9,
"status": "active",
"created_on": "2017-11-29T18:07:55.000000Z",
"modified_on": "2020-09-02T16:09:03.000000Z"
},
{
"id": "427",
"targets": [
{
"target": "url",
"constraint": {
"operator": "matches",
"value": "nz.example.org/*"
}
}
],
"actions": [
{
"id": "ssl",
"value": "flexible"
}
],
"priority": 8,
"status": "active",
"created_on": "2017-11-29T18:08:00.000000Z",
"modified_on": "2020-09-02T16:09:03.000000Z"
}
]
}
我想要做的是提取嵌套在 constraint.value 字段中用于 always_use_https 操作的 url。目标是提取值并将它们 return 作为 json 数组。我想到的是:
jq '[
[
[
[
.[] | .[] | select(.actions[].id | contains("always_use_https"))
] | .[].targets[] | select(.target | contains("url"))
] | .[] | .constraint | select(.operator | contains("matches"))
] | .[].value
]'
针对我们的例子,这会产生:
[
"http://ng.example.org/*",
"http://nz.example.org/*"
]
在 jq 中有没有更简洁的方法来实现这个?
这会根据我理解的标准产生预期的输出:
jq '.["example.org"]
| map(select( any(.actions[]; .id == "always_use_https"))
| .targets[]
| select(.target == "url")
| .constraint.value )
' cloudfare.json