英文:
JQ: check if substring from key exists in an array
问题
我有一个包含对象的数组作为输入,每个对象如下所示:
{
"downloadDir": "/merge/downloads",
"id": 2485,
"labels": [
"irrelevant",
"downloads"
]
}
我试图让 JQ 遍历每个对象并找出那些在.labels
数组中没有一个元素是.downloadDir
第一个和第二个'/'之间的子字符串的对象,即
- 对于"/merge/downloads",应该是"downloads"
- 对于"/merge/tv/downloads",应该是"tv"
- 对于"/merge/tv-share/downloads",应该是"tv-share"
对于匹配的对象,它应该返回它们的.id。
经过查看Stack Overflow上的一些类似问题,我认为逻辑应该是这样的:map(select(.labels | index(.downloadDir)))
。如果我在index()
中有一个静态字符串,比如map(select(.labels | index("downloads")))
,这个方法有效,但我无法使其与.downloadDir
一起工作:它会抛出"Cannot index array with string "downloadDir""或"Cannot index string with string "labels"",这取决于我是否将输入传递为数组。
我完全不知道如何处理将正则表达式应用于.downloadDir
以获取所需的子字符串。
英文:
I have an array of objects as input, each object looking as follows:
{
"downloadDir": "/merge/downloads",
"id": 2485,
"labels": [
"irrelevant",
"downloads"
]
}
I am trying to have JQ go through every object and find those, which do not have an element in the .labels array that is a substring of .downloadDir between 1st and 2nd '/', i.e.
- for "/merge/downloads" it should be "downloads"
- for "/merge/tv/downloads" it should be "tv"
- for "/merge/tv-share/downloads" it should be "tv-share"
For matching objects it should return their .id.
Having reviewed some similar questions on Stack Overflow, I'm thinking the logic is supposed to look something like this: map(select(.labels | index(.downloadDir))). This works if I have a static string in index(), like map(select(.labels | index("downloads"))), however I can't get it to work with .downloadDir: it throws out "Cannot index array with string "downloadDir"" or "Cannot index string with string "labels"", depending on whether I pass the input as an array or not.
I am entirely unsure how to approach applying a regex to .downloadDir to grab the needed substring from it.
答案1
得分: 0
我在输入中添加了一个对象进行测试:
[{
"downloadDir": "/merge/downloads",
"id": 2485,
"labels": [
"irrelevant",
"downloads"
]
},{
"downloadDir": "/merge/tv/downloads",
"id": 2486,
"labels": [
"irrelevant",
"downloads"
]
}]
以下表达式返回了第一个对象的id
,而不是第二个:
<file.json jq '.[]
| (.downloadDir | split("/")\[2\]) as $key
| select(.labels | map(. != $key) | all).id'
英文:
I added one more object into the input for testing:
[{
"downloadDir": "/merge/downloads",
"id": 2485,
"labels": [
"irrelevant",
"downloads"
]
},{
"downloadDir": "/merge/tv/downloads",
"id": 2486,
"labels": [
"irrelevant",
"downloads"
]
}]
The following expression returned the id
of the first object, not the second:
<file.json jq '.[]
| (.downloadDir | split("/")[2]) as $key
| select(.labels | map(. != $key) | all).id'
答案2
得分: 0
jq 'select(any(.labels[] == (.downloadDir / "/")[2]; .)).id' input.json
2485
这适用于一系列项目的流(与您的示例建议的一样)。如果您的输入确实是一组项目,请在前面加上 .[]
。
英文:
Split the .downloadDir
at "/"
using /
, and take the second item. Compare it to each item in .labels
and yield true
if at least one (any
) matches. select
those items, and output the .id
.
jq 'select(any(.labels[] == (.downloadDir / "/")[2]; .)).id ' input.json
2485
This works on a stream of items (as suggested by your sample). If your input is indeed an array of items, prepend .[]
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论