Your statement does not work, because you try to feed the data object into match, but match can only work on strings.
The following expression will do what you want. The to_entries converts the object to an array of keys and values. Then we iterate over this array by using map and select all entries where the .key (now a string) has a match. Finally we just print out the value of every element.
.data | to_entries | map(select(.key | match("what a burger";"i"))) | map(.value)
However, two comments:
- The
[a,a,3]is not allowed in JSON, becauseais not a number. - It works because the keys ARE actually different, even if only the letter case is not equal. If at least two keys are identical, you will run into problems, because keys should be unique. In fact,
jqwill only output one of the elements then.
Your statement does not work, because you try to feed the data object into match, but match can only work on strings.
The following expression will do what you want. The to_entries converts the object to an array of keys and values. Then we iterate over this array by using map and select all entries where the .key (now a string) has a match. Finally we just print out the value of every element.
.data | to_entries | map(select(.key | match("what a burger";"i"))) | map(.value)
However, two comments:
- The
[a,a,3]is not allowed in JSON, becauseais not a number. - It works because the keys ARE actually different, even if only the letter case is not equal. If at least two keys are identical, you will run into problems, because keys should be unique. In fact,
jqwill only output one of the elements then.
Here's a slightly briefer alternative:
.data | with_entries(select(.key|match("what a burger";"i")))[]
After rectifying the input, and using jq's -c option, this would produce the two lines:
[1,2,3]
["a","a",3]
bash - Match keys with regex in jq - Unix & Linux Stack Exchange
jq - Matching When Value Is List - Stack Overflow
scripting - jq select match pattern but not if preceded by other pattern - Unix & Linux Stack Exchange
json - jq - select an attribute beginning with a string - Unix & Linux Stack Exchange
If you wanted exact match, save following into script.jq :
.[] | select(.Type == $match) | .Code
Then test with
$ jq -r --argjson match '["A"]' -f script.jq test.json
DEF
$ jq -r --argjson match '["B"]' -f script.jq test.json
GHI
$ jq -r --argjson match '["A", "B"]' -f script.jq test.json
JKL
The jq program
.[] | select(any(.Type[]; IN("A","B","A, B","Universal"))) | .Code
produces:
"DEF"
"GHI"
"JKL"
"MNO"
With
jq 'map_values(select(.value == "auto"))' file
... you pull out the parts of the top-level object that you are interested in:
{
"package2": {
"name": "package_2",
"value": "auto"
}
}
With map_values(expression), you apply expression to each sub-part of the input object. In this case, the part is kept if the test in the select() statement evaluates to true, and discarded otherwise. It's similar to map(expression), but you'd use map() on arrays and map_values() on objects.
From there, you can choose to get the top-level key:
$ jq -r 'map_values(select(.value == "auto"))|keys[]' file
package2
The keys function creates an array of all keys in the input object, and the [] at the end expands the array into a set of strings.
Note that if there are multiple sub-objects with auto as their .value key's value, you will get multiple strings out of this command.
For a brief moment, I was unsure whether you wanted the value of the .name key or the top-level key. Once I spotted that you only wanted the top-level key, I had already written the text below. I'm leaving it in as a sort of comment.
$ jq -r 'map_values(select(.value == "auto"))[].name' file
package_2
Using [].name at the end, expand the top-level object into a set of sub-objects and then extract the .name key's value from each.
This last one could also have been written
$ jq -r 'map_values(select(.value == "auto").name)[]' file
package_2
... which reduces the original object to only
{
"package2": "package_2"
}
... and then extracts the values of all remaining keys with the trailing [].
You can use jq's select() function:
jq -r '.[] | select(.value=="auto").name'
Also your json example is currently invalid.
I have a JSON. How to get the value of time of the last object that matches the criteria: .type == "StateChanged" and .data.to == "idle" state?
In the JSON, the last object happens to match this criteria, therefore its time 2024-05-03T18:33:44.407703553-06:00 should be printed.
Much appreciated.