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]
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.
Found out the answer
jq 'select(.items | index("blue"))'
On Jan 30, 2017, a builtin named IN was added for efficiently testing whether a JSON entity is contained in a stream. It can also be used for efficiently testing membership in an array. In the present case, the relevant usage would be:
select( .items as $items | "blue" | IN($items[]) )
If your jq does not have IN/1, then so long as your jq has first/1, you can use this equivalent definition:
def IN(s): . as $in | first(if (s == $in) then true else empty end) // false;
any/0
Using any/0 here is relatively inefficient, e.g. compared to using any/1:
select( any( .items[]; . == "blue" ))
(In practice, index/1 is usually fast enough, but its implementation currently (jq 1.5 and versions through at least July 2017) is suboptimal.)