MaryCoding
MaryCoding

Reputation: 664

jq - looping through json object and only displaying certain values

I am currently learning how to usage jq. I have a json object and I am able to loop and read values with jq as such cat test.json | jq -r '.test'. However, I am running into some complexity when I only want to display on values that have outdated or deprecated = true but ommit from result if relase = never-update-app or never-upgrade-app. I am trying cat test.json | jq '.test | select(.[].outdated==true)' but this is not returning the desired results. Is this something possible through jq and have it display in the below desired format?

My desired output is shown below:

Release Name                                             Installed    Latest    Old      Deprecated
test-app                                                 1.0.0        2.0.0     true     false  

json:

{
    "test": [{
        "release": "myapp1",
        "Installed": {
            "version": "0.3.0",
            "appVersion": "v1.2.6"
        },
        "Latest": {
            "version": "",
            "appVersion": ""
        },
        "outdated": false,
        "deprecated": false
    }, {
        "release": "myapp2",
        "Installed": {
            "version": "6.5.13",
            "appVersion": "1.9.1"
        },
        "Latest": {
            "version": "",
            "appVersion": ""
        },
        "outdated": false,
        "deprecated": false
    }, {
        "release": "test-app",
        "Installed": {
            "version": "1.0.0",
            "appVersion": ""
        },
        "Latest": {
            "version": "2.0.0",
            "appVersion": ""
        },
        "outdated": true,
        "deprecated": false
    }, {
        "release": "never-update-app",
        "Installed": {
            "version": "1.0.0",
            "appVersion": ""
        },
        "Latest": {
            "version": "3.0.0",
            "appVersion": ""
        },
        "outdated": true,
        "deprecated": false
    }, {
        "release": "never-upgrade-app",
        "Installed": {
            "version": "2.0.0",
            "appVersion": ""
        },
        "Latest": {
            "version": "2.0.0",
            "appVersion": ""
        },
        "outdated": false,
        "deprecated": true
    }]
}

Upvotes: 0

Views: 1924

Answers (2)

Logan Lee
Logan Lee

Reputation: 997

Filter

(["ReleaseName","Installed","Latest","Old","Deprecated"] | @tsv), (.test[] | select(   (.outdated==true or .deprecated==true) and ((.release=="never-update-app" or .release=="never-upgrade-app") | not)   ) | "\(.release) \(.Installed.version) \(.Latest.version) \(.outdated) \(.deprecated)" / " " | @tsv)

Output

ReleaseName Installed   Latest  Old Deprecated
test-app    1.0.0   2.0.0   true    false

Demo

https://jqplay.org/s/B4a5cxlL28

Upvotes: 0

Weeble
Weeble

Reputation: 17960

How to act on each element in an array

You have an array in .test. If you want to extract the individual elements of that array to use in the rest of your filter, use .test[]. If you want to process them but keep the results in an array, use .test|map(...) where ... is the filter you want to apply to the elements of the array.

How to filter objects with multiple conditions

As described in this question you can use the select() filter with multiple conditions. So, for example:

jq '.test[]|
    select(
        (.outdated or .deprecated) and
        .release != "never-update-app" and
        .release != "never-upgrade-app"
    )'

How to combine non-trivial filters

Use parentheses! As an example, suppose you want to replace the two "never-" tests with a startswith test. By surrounding the pipes with parentheses you isolated the calculation and just get the true/false answer to combine in a boolean expression.

jq '.test[]|
    select(
        (.outdated or .deprecated) and
        (.release|startswith("never-")|not)
    )'

How to format results in a table

I think this answer on formatting results in a table is probably sufficient. If you have more specific needs I think you might want to spin this off into a separate question.

Upvotes: 2

Related Questions