user630702
user630702

Reputation: 3097

JQ - Append json data before and after

I want to append some keys and values and object before the jq output and then at the end append auth and ID. How can I do that?

For Case 1 - At the beginning I want to append this

{
    "jsonrpc": "2.0",
    "method": "host.get",
    "params":
        "filter": {

and at the end the following.

},
    "auth": "038e1d7b1735c6a5436ee9eae095879e",
    "id": 1
}

Any suggestions?

Case 1:

echo $hosts
host001 host002 host003

echo $hosts | jq -R 'split (" ")' | jq -s '{hosts:map({"hostid":.})}'
{
  "hosts": [
    {
      "hostid": [
        "host001",
        "host002",
        "host003"
      ]
    }
  ]
}

But I want to output like this which includes jsonrpc, methods, params, filter and then the host array needs to be added and in the end append auth and id.

Expected Query 1:

{
    "jsonrpc": "2.0",
    "method": "host.get",
    "params": {
        "filter": {
            "hostid": [
                "host001",
                "host002",
                "host003"
            ]
        }
    },
    "auth": "038e1d7b1735c6a5436ee9eae095879e",
    "id": 1
}

Case 2:

I want to append the jsonrpc, methods params etc, but also append $hostid_json after $groupid_json and then append auth, id etc., as show in query 2.

echo $group_id
92 93

groupid_json=$(echo $group_id | jq -R 'split (" ")'  | jq '.[]'  | jq -s '{groups:map({"groupid":.})}')
{ "groups": [ { "groupid": "92" }, { "groupid": "93" } ] }

echo $hosts_id
1111 2222

hostid_json=$(echo $hosts_id | jq -R 'split (" ")'  | jq '.[]'  | jq -s '{hosts:map({"hostid":.})}')
{ "hosts": [ { "hostid": "1111" }, { "hostid": "2222" } ] }

But the final ouput I need is like the following.

Expected Query 2:

{
    "jsonrpc": "2.0",
    "method": "hostgroup.massadd",
    "params": {
        "groups": [
            {
                "groupid": "92"
            },
            {
                "groupid": "93"
            }
        ],
        "hosts": [
            {
                "hostid": "1111"
            },
            {
                "hostid": "2222"
            }
        ]
    },
    "auth": "f223adf833b2bf2ff38574a67bba6372",
    "id": 1
}

Upvotes: 2

Views: 397

Answers (1)

Inian
Inian

Reputation: 85530

You don't have to use raw input mode to any of the cases above, but just use the --argjson flag to include the array directly into the filter. So your first case just becomes

jq -n --argjson hosts '["host001", "host002", "host003"]' \
       '{ 
           jsonrpc: "2.0", 
           method: "host.get", 
           params: {filter: {"hostid": $hosts}}, 
           auth: "038e1d7b1735c6a5436ee9eae095879e", 
           id: 1  
        }'

and case two becomes

jq -n --argjson group_id '["92", "93"]' --argjson hosts_id '["1111", "2222"]' \
       '{ 
           jsonrpc: "2.0", 
           method: "hostgroup.massadd", 
           params: { 
             groups: (reduce $group_id[] as $g (.; . + [{ group_id: $g }])), 
             hosts:  (reduce $hosts_id[] as $h (.; . + [{ hostid: $h }])) 
           }, 
           auth: "038e1d7b1735c6a5436ee9eae095879e", 
           id: 1  
        }'

The -n is for null input mode used when constructing JSON from scratch, i.e. to run a filter without needing any input files. The reduce() function runs iteratively on each input object and . + [{ group_id: $g }] creates a JSON object for each value of group_id created.

Using dynamic values in argument fields

If you do not want to hardcode values in argjson and want to make it dynamically configurable from a variable, use a placeholder like an array to store multiple values

Case: 1

hosts=(host001 host002 host003)

jq -n --arg hosts_arg "${hosts[*]}" \
       '{
           jsonrpc: "2.0",
           method: "host.get",
           params: {filter: {"hostid": ($hosts_arg | split(" "))}},
           auth: "038e1d7b1735c6a5436ee9eae095879e",
           id: 1
        }'

Case 2:

groupid=(92 93)
hostid=(1111 2222)

jq -n --arg group_id "${groupid[*]}" --arg hosts_id "${hostid[*]}" \
       '{
           jsonrpc: "2.0",
           method: "hostgroup.massadd",
           params: {
           groups: (reduce ($group_id | split(" ")[]) as $g (.; . + [{ group_id: $g }])),
           hosts:  (reduce ($hosts_id | split(" ")[]) as $h (.; . + [{ hostid: $h }]))
           },
           auth: "038e1d7b1735c6a5436ee9eae095879e",
           id: 1
        }'

Note that this approach doesn't work, if your group_id or host_id contains strings that has spaces.

Upvotes: 1

Related Questions