parsing json file with jq [closed] - json

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
{
"name": "ford",
"availableVersions": [
{
"version": 111,
"count": 3
},
{
"version": 122,
"count": 2
},
{
"version": 133,
"count": 3
},
{
"version": 144,
"count": 1
}
],
"RealVersion": 155
}
{
"name": "bmw",
"availableVersions": [
{
"version": 244,
"count": 1
},
{
"version": 255,
"count": 3
} ],
"RealVersion": 120
}
I have this demo.json file now if (name == 'ford')(name can be a variable) I want to get the all the versions whose count != 3
and if all the version's count == 3 I want to get the RealVersion of ford so in this case output should be.
EXPECTED OUTPUT = [122 144 ]
I am using jq tool for parsing the json file
Now if all the version count ==3
{
"name": "ford",
"availableVersions": [
{
"version": 111,
"count": 3
},
{
"version": 122,
"count": 3
},
{
"version": 133,
"count": 3
},
{
"version": 144,
"count": 3
}
],
"RealVersion": 155
}
{
"name": "bmw",
"availableVersions": [
{
"version": 244,
"count": 1
},
{
"version": 255,
"count": 3
} ],
"RealVersion": 120
}
Now in this case all the version's count == 3 so now I want to get the real version which is 155
EXPECTED OUTPUT SHOULD BE 155
CAN ANYONE HELP ME WITH THIS?

The following program, when invoked with the -n command-line option, produces the expected output in both cases:
inputs
| .RealVersion as $RealVersion
| select(.name == "ford")
| .availableVersions
| map(select(.count != 3))
| if length > 0 then map(.version)
else $RealVersion
end
Specifically, in the first case, it produces a JSON array, and in the second case, the actual value of .ReadVersion.

Related

How to filter an array of json with jq in linux?

I have the following JSON input:
{
"paging": {
"count": 0,
"total": 0,
"offset": 0,
"max": 0
},
"executions": [
{
"id": 5,
"href": "https://localhost.com.br",
"permalink": "https://localhost.com.br",
"status": "succeeded",
"project": "PROJETO",
"executionType": "scheduled",
"date-started": {
"unixtime": 1660793400012,
"date": "2022-08-18T03:30:00Z"
},
"date-ended": {
"unixtime": 1660793409694,
"date": "2022-08-18T03:30:09Z"
},
"job": {
"id": "cdkwednweoi-8745bjdf-kcjkjr8745",
"averageDuration": 0,
"name": "routine",
"group": "",
"project": "PROJECT",
"description": "",
"href": "https://localhost.com.br",
"permalink": "https://localhost.com.br"
},
"description": "runner",
"argstring": null,
"serverUUID": "jdnsdnasldnaje382nf5ubv",
"successfulNodes": [
"84jsk937nf"
]
}
]
}
First I want to select an array by a property name. And then I want to select an object of the array by the value of the propertyes.
Example of the desired informations on output:
"href"
"status"
"project"
"date-started":
"unixtime": 48298437239847,
"date": "2022-07-17"
"date-ended":
"unixtime": 48298437239847,
"date": "2022-07-17"
"job":
"name": "cleaner"
I knew how to get the firts values:
jq -r '.executions[] | [.href, .status, .project']
But the other ones I don't know how to do, I've tried with:
jq '.executions[] | with_entries( select(.value | has("date-started") ) )'
But it doesn't works.
Your first query produces a JSON array, so in this response, I'll assume it will suffice to produce an array of the eight values of interest in the order you've specified.
With your input, the following invocation produces the eight values as shown below:
jq '.executions[]
| [.href, .status, .project,
(."date-started" | (.unixtime, .date)),
(."date-ended" | (.unixtime, .date)),
.job.name]'
Output:
[
"https://localhost.com.br/rundeck/api/40/execution/2340",
"succeeded",
"PROJETO",
1660793400012,
"2022-08-18T03:30:00Z",
1660793409694,
"2022-08-18T03:30:09Z",
"proc_limpeza_saft"
]

jq - how to format pairs of keys and values, then iterate keys in json

Please help me, guys.
I have the following:
{
"id": 88888,
"name": "TESTING",
"online": 1,
"test_list": [
{
"id": 0,
"type": 34,
"name": "Blabla",
"used": 9870,
"rate": 31768897891,
"temp": 0,
"percent": 100,
"enabled": 0,
"reset": 0,
"temp": 2
},
{
"id": 1,
"type": 23,
"name": "AlbAlb",
"used": 0865,
"rate": 317681675432345678951,
"temp": 1,
"percent": 99,
"enabled": 0,
"reset": 0,
"target": 2
},
{
"id": 2,
"type": 98,
"name": "TztS",
"used": 65,
"rate": 6324,
"temp": 0,
"percent": 80,
"enabled": 0,
"reset": 0,
"target": 2
}
],
"info": {
"version": "1.0",
"no": "123",
"sw": "321",
"version_detail": {
"date": "2021-03-30",
"build": "11",
"cot": "dfgdfgd"
}
}
}
And i need to do the following:
[
{
"name": "TESTING",
"online": 1
},
{
"id0": 0,
"type0": 34,
"name0": "Blabla",
"rate0": 31768897891,
"temp0": 0,
"percent0": 100
"id1": 1,
"type1": 23,
"name1": "AlbAlb",
"rate1": 317681675432345670000,
"temp1": 1,
"percent1": 99
"id2": 2,
"type2": 98,
"name2": "TztS",
"rate2": 6324,
"temp2": 0,
"percent2": 80
}
]
I want to join the information, what I need into blocks and then set the key numbering by id or iterate.
Will it be possible to somehow realised it using jq and man in one line?
After a long time, I managed to do only the following:
jq '[. | {name,online}] + [.test_list[] | {id,type,name,rate,temp,percent} | with_entries(.key |= . + "0")]'
I tried using map tool, but it doesn't work = (( Help Please...
Here's a reduce-free approach: it uses with_entries on an array to do the counting:
[ {name, online},
(.test_list
| with_entries(.key |= tostring
| .key as $k
| .value |= with_entries(.key += $k))
| add
)
]
The key is with_entries. One possibility would be to use reduce:
[ {name, online},
(.test_list
| . as $in
| reduce range(0; length) as $i ({}; . + ($in[$i] | with_entries(.key = "\(.key)\($i)")))
)
]
Please note that your example output is not quite correct as JSON, and that with your example input, the above jq program produces slightly different results, but if you want to remove certain key-value pairs, you can easily do that, e.g. as a preliminary step in the pipeline.

Concatenate name and number field from JSON structure in jq

{
"name": "ford",
"availableVersions": [
{
"version": 111,
"count": 3
},
{
"version": 122,
"count": 2
}
]
}
{
"name": "bmw",
"availableVersions": [
{
"version": 133,
"count": 1
},
{
"version": 144,
"count": 3
}
]
}
I have this demo.json file now if (count == 3) I want to concatenate the name with the version.
So my output should be [ford-111, BMW-144]. I am using json parsing with jq.
I tried this command
cat demo2| jq ' select(.availableVersions[].count == 3) | .name + ": " + (.availableVersions[].version|tostring)'
Output:
"ford: 111"
"ford: 122"
"bmw: 133"
"bmw: 144"
Expected output:
"ford: 111"
"bmw: 144"
Can anybody help me with this?
You nearly had it, you just need to move the select to the other side.
.name + ": " + (.availableVersions[]|select(.count == 3).version|tostring)
Though I'd write it using string interpolation instead:
"\(.name): \(.availableVersions[]|select(.count == 3).version)"

How to parse this file with jq?

I just started using jq and json files, and I'm trying to parse a specific file.
I'm tring to do it with jq in command line, but if there's any other way to do it properly, I'm in to give it a try.
The file itself looks like this :
{
"Status": "ok",
"Code": 200,
"Message": "",
"Result": [
{
"ID": 123456,
"Activity": 27,
"Name": Example1",
"Coordinate": {
"Galaxy": 1,
"System": 22,
"Position": 3
},
"Administrator": false,
"Inactive": false,
"Vacation": false,
"HonorableTarget": false,
"Debris": {
"Metal": 0,
"Crystal": 0,
"RecyclersNeeded": 0
},
"Moon": null,
"Player": {
"ID": 111111,
"Name": "foo",
"Rank": 4
},
"Alliance": null
},
{
"ID": 223344,
"Activity": 17,
"Name": "Example2",
"Coordinate": {
"Galaxy": 3,
"System": 44,
"Position": 5
},
"Administrator": false,
"Inactive": false,
"Vacation": false,
"StrongPlayer": false,
"HonorableTarget": false,
"Debris": {
"Metal": 0,
"Crystal": 0,
"RecyclersNeeded": 0
},
"Moon": null,
"Player": {
"ID": 765432,
"Name": "Player 2",
"Rank": 3
},
"Alliance": null
},
(...)
]
}
I would need to extract information based on the galaxy/system/position.
For example, having a script with the proper filters in it and execute something like that :
./parser --galaxy=1 --system=22 --position=3
And it would give me :
ID : 123456
Name : Example1
Activity : 27
...
I tried to do that with curl to grab my json file and jq to parse my file, but I have no idea how I can make that kind of request.
The following should be sufficient to get you on your way.
First, let's assume the JSON is in a file name galaxy.json; second, let's assume the file galaxy.jq contains the following:
.Result[]
| select(.Coordinate | (.Galaxy==$galaxy and .System==$system and .Position==$position))
Then the invocation:
jq -f so-galaxy.jq --argjson galaxy 1 --argjson system 22 --argjson position 3 galaxy.json
would yield the corresponding object:
{
"ID": 123456,
"Activity": 27,
"Name": "Example1",
"Coordinate": {
"Galaxy": 1,
"System": 22,
"Position": 3
},
"Administrator": false,
"Inactive": false,
"Vacation": false,
"HonorableTarget": false,
"Debris": {
"Metal": 0,
"Crystal": 0,
"RecyclersNeeded": 0
},
"Moon": null,
"Player": {
"ID": 111111,
"Name": "foo",
"Rank": 4
},
"Alliance": null
}
Key: Value format
If you want the output to be in key: value format, simply add -r to the command-line options, and append the following to the jq filter:
| to_entries[]
| "\(.key): \(.value)"
Output
ID: 123456
Activity: 27
Name: Example1
Coordinate: {"Galaxy":1,"System":22,"Position":3}
Administrator: false
Inactive: false
Vacation: false
HonorableTarget: false
Debris: {"Metal":0,"Crystal":0,"RecyclersNeeded":0}
Moon: null
Player: {"ID":111111,"Name":"foo","Rank":4}
Alliance: null

Filter JSON outer objects including only one maximal object from inner array with jq

I have a slightly modified JSON file with iOS firmware information from https://api.ipsw.me/v2.1/firmwares.json. This is a simplified version:
Input
{
"AppleTV5,3": {
"firmwares": [
{
"version": "9.2",
"buildid": "13Y234"
},
{
"version": "9.1.1",
"buildid": "13U717"
},
{
"version": "9.1",
"buildid": "13U85"
}
],
"bdid": 52,
"name": "Apple TV 4 (2015)"
},
"AppleTV3,2": {
"firmwares": [
{
"version": "8.4.1",
"buildid": "12H523"
},
{
"version": "8.3",
"buildid": "12F69"
}
],
"bdid": 0,
"name": "Apple TV 3 (2013)"
},
"AppleTV3,1": {
"firmwares": [
{
"version": "8.4.1",
"buildid": "12H523"
},
{
"version": "8.3",
"buildid": "12F69"
},
{
"version": "8.2",
"buildid": "12D508"
}
],
"bdid": 0,
"name": "Apple TV 3"
}
}
I want to write a jq query that returns each outer object with only the latest firmware object in the firmwares array. E.g.:
Desired output
{
"AppleTV5,3": {
"firmwares": [
{
"version": "9.2",
"buildid": "13Y234"
}
],
"bdid": 52,
"name": "Apple TV 4 (2015)"
},
"AppleTV3,2": {
"firmwares": [
{
"version": "8.4.1",
"buildid": "12H523"
}
],
"bdid": 0,
"name": "Apple TV 3 (2013)"
},
"AppleTV3,1": {
"firmwares": [
{
"version": "8.4.1",
"buildid": "12H523"
}
],
"bdid": 0,
"name": "Apple TV 3"
}
}
I can get a list of the latest firmwares objects with:
.[].firmwares | max_by(.version)
I can get just the values from version with:
.[].firmwares | map(.version | values) | max
And I can get the outer AppleTV objects with firmwares matching a particular version:
[ . | to_entries[] | .value.firmwares |= map ( select ( .version == "8.3" ) ) ] | from_entries
But I can't seem to combine the techniques to get my desired output. Can anyone help out?
You should think of it as updating the firmwares arrays. We're updating it with a filtered version where it the max version is selected.
.[].firmwares |= [ max_by(.version | split(".") | map(tonumber)) // empty ]
Here is a solution which uses reduce to visit each key of the object and update corresponding .firmwares to the latest version
reduce keys[] as $i (
.
; .[$i].firmwares |= [max_by(.version)]
)