leitmedium
leitmedium

Reputation: 23

How to apply function to multiple fields in jq

I try to reduce the size of a jq call. The current command is:

jq '.result | .[].newValueJson.action |= (. | tostring // .) | .[].oldValueJson.action |= (. | tostring // .) | .[].metadata.value |= (. | tostring // .)'

As you can see, the function "tostring" is being applied to "newValueJson.action", "oldValueJson.action" and "metadata.value" in just the same way. I am wondering if there is a more compact syntax so I only need to apply tostring once?

I extracted sample data show what is being done (this is not the full json tree).

Source:

{
    "result": [{
            "id": 1,
            "action": {
                "result": true,
                "type": "filter_create"
            },
            "newValueJson": {
                "action": "simulate"
            },
            "oldValueJson": {
                "action": "enforce"
            },
            "metadata": {
                "value": false
            }
        },
        {
            "id": 2,
            "action": {
                "result": true,
                "type": "filter_create"
            },
            "newValueJson": {
                "action": {
                    "mode": "simulate",
                    "timeout": 3600
                }
            },
            "oldValueJson": {
                "action": {
                    "mode": "enforce",
                    "timeout": 3600
                }
            },
            "metadata": {
                "value": "off"
            }
        }
    ]
}

Result:

[{
        "id": 1,
        "action": {
            "result": true,
            "type": "filter_create"
        },
        "newValueJson": {
            "action": "simulate"
        },
        "oldValueJson": {
            "action": "enforce"
        },
        "metadata": {
            "value": "false"
        }
    },
    {
        "id": 2,
        "action": {
            "result": true,
            "type": "filter_create"
        },
        "newValueJson": {
            "action": "{\"mode\":\"simulate\",\"timeout\":3600}"
        },
        "oldValueJson": {
            "action": "{\"mode\":\"enforce\",\"timeout\":3600}"
        },
        "metadata": {
            "value": "off"
        }
    }
]

Thanks and Best.

Upvotes: 1

Views: 1522

Answers (1)

Inian
Inian

Reputation: 85855

You can group the actions together using (..) as below. Also instead of using the array notation .[], you can use map(..) to handle apply the filter expression inside the result array

.result | map((.newValueJson.action, .oldValueJson.action, .metadata.value ) |= (. | tostring // .))

Upvotes: 1

Related Questions