The -r option should not be used if the output will be fed into another JSON parser; only the last jq in the pipeline should use it – otherwise you risk feeding non-JSON data into the second jq instance.
Your last example with .[0].t seems correct and works with jq 1.6.
$ cat json | jq '.tx' | jq -r '.[0].t'
t for a
But this can be simplified to a single jq invocation, first incrementally to:
$ cat json | jq -r '.tx | .[0].t'
t for a
and then finally to:
$ cat json | jq -r '.tx[0].t'
t for a
Answer from grawity on Stack Exchangejson - Select objects based on value of variable in object using jq - Stack Overflow
jq: Extract element from object or array of objects
shell - Get value of JSON [] array in jq - Unix & Linux Stack Exchange
Using JQ to return the index number where an element in an array has a specific value.
Adapted from this post on Processing JSON with jq, you can use the select(bool) like this:
$ jq '.[] | select(.location=="Stockholm")' json
{
"location": "Stockholm",
"name": "Walt"
}
{
"location": "Stockholm",
"name": "Donald"
}
To obtain a stream of just the names:
$ jq '.[] | select(.location=="Stockholm") | .name' json
produces:
"Donald"
"Walt"
To obtain a stream of corresponding (key name, "name" attribute) pairs, consider:
$ jq -c 'to_entries[]
| select (.value.location == "Stockholm")
| [.key, .value.name]' json
Output:
["FOO","Donald"]
["BAR","Walt"]
Given the following JSON, what is the best way to extract the phone numbers, whether inside an object or an array of objects?
{
"phones": {
"Alex Baker": { "location": "mobile", "number": "+14157459038" },
"Bob Clarke": [
{ "location": "mobile", "number": "+12135637813" },
{ "location": "office", "number": "+13104443200" }
],
"Carl Davies": [
{ "location": "office", "number": "+14083078372" },
{ "location": "lab", "number": "+15102340052" }
],
"Drew Easton": { "location": "office", "number": "+18057459038" }
}
}I'm using the following query, but I wonder if there's a better way to do this:
$ cat phones.json | jq '.phones | to_entries | [ .[].value | objects | .number ] + [ .[].value | arrays | .[].number ]' [ "+14157459038", "+18057459038", "+12135637813", "+13104443200", "+14083078372", "+15102340052" ]
Any suggestions will be appreciated, thanks!
I think this is fairly easy to achieve for this inner list. The values seem to be all zero's so...
jq '.[][1]' < yourjsonfile
Just to provide another approach. When working with lists, dicts and other types python is the right tool. To give you an idea on how you could retrieve the values from the list you'd do something lik:
#!/usr/bin/env python
mylist = [[1645128660000,0],[1645128720000,0],[1645128780000,0],[1645128840000,0],[1645128900000,0],[1645128960000,0],[1645129020000,0],[1645129080000,0],[1645129140000,0],[1645129200000,0]]
for k,v in mylist:
print("Key":,k)
print("Value":v)
Or using list comprehension
[v for k,v in mylist]
should be sufficient. There is also this awesome page where you can play around with jq: https://jqplay.org/#
If we assume that the input is an array of elements and that each element looks like [key, value] with integer keys and values, then we may extract the value for a given key using the below command:
mykey=1645128900000
jq --argjson key "$mykey" '.[] | select(first == $key) | last' file
This selects all the array entries with the given key as its first element and then extracts the value, the last element, from each piece chosen.
I managed to do this when I was teaching myself JSON and playing with JQ. Now I can't remember how I did this. So any guidance would be of value.
Take the following file: settings.json
{
"Bot_API_Key": "SuperSecretKey",
"Channels": [
{
"Channel_Name": "First Channel",
"Channel_Short": "ch01",
"Channel_ID": 4004841050681
},
{
"Channel_Name": "Second Channel",
"Channel_Short": "ch02",
"Channel_ID": 4004685917007
}
]
}If I use the following:
jq '.Channels[] | contains("ch02")' settings.jsonIt returns:
false true
What I actually need is the index number in the array. In this case it must return 1.
I did achieve this once, a few weeks back, when experimenting, and now I can't repeat the results. Like a fool, I didn't document everything I did.
This jq query works for me with the JSON for Docker:
.artifacts[] | arrays[0] | select(endswith(".app"))
The arrays filter selects arrays from elements of artifacts, and then we can look for the first elements of these arrays for one which ends with .app.
A similar query as what muru has, but returns all artefacts in any artifacts array if any of the entries in the array ends with the string .app:
.artifacts[] | select(type == "array" and any(endswith(".app")))[]
or,
.artifacts[] | arrays | select(any(endswith(".app")))[]
So if an application has some artefact thething.app and someotherthing.quux in the same array, then both are returned.
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.