Home > Back-end >  Extracting values from nested arrays
Extracting values from nested arrays

Time:05-18

I'm trying to extract values from nested arrays in JSON below and output as CSV.

Fields to extract:

templates.name  
items.name  
triggers.name

Output as:
templates.name; items.name; triggers.name

Anticipated output something like:

"Template App Agent"; "Host name of zabbix_agentd running"; "Host name of zabbix_agentd was changed on {HOST.NAME}"
"Template App Agent"; "Agent ping"; "Zabbix agent on {HOST.NAME} is unreachable for 5 minutes"
"Template App Agent"; "Version of zabbix_agent(d) running"; ""

Note:
Not every item has a trigger.
Several triggers may exist for an item.

I'm new to JQ. So far only success is extracting the template name.

jq '.[] | {templates: [.templates[].name]}'

Data:

{
    "zabbix_export": {
        "version": "5.4",
        "date": "2022-05-17T06:25:59Z",
        "groups": [
            {
                "uuid": "7df96b18c230490a9a0a9e2307226338",
                "name": "Templates"
            }
        ],
        "templates": [
            {
                "uuid": "e60e6598cf19448089a5f5a6c5d796a2",
                "template": "Template App Agent",
                "name": "Template App Agent",
                "groups": [
                    {
                        "name": "Templates"
                    }
                ],
                "items": [
                    {
                        "uuid": "24c03ed734d54dc8868a282a83a02200",
                        "name": "Host name of zabbix_agentd running",
                        "key": "agent.hostname",
                        "delay": "1h",
                        "history": "1w",
                        "trends": "0",
                        "value_type": "CHAR",
                        "request_method": "POST",
                        "tags": [
                            {
                                "tag": "Application",
                                "value": "Zabbix agent"
                            }
                        ],
                        "triggers": [
                            {
                                "uuid": "d2d12d9e7dfe4fedb252f19b85e5e6aa",
                                "expression": "(last(/Template App Agent/agent.hostname,#1)<>last(/Template App Agent/agent.hostname,#2))>0",
                                "name": "Host name of zabbix_agentd was changed on {HOST.NAME}",
                                "priority": "INFO"
                            }
                        ]
                    },
                    {
                        "uuid": "abacad4ca5eb46d29864d8a4998f1cbb",
                        "name": "Agent ping",
                        "key": "agent.ping",
                        "history": "1w",
                        "description": "The agent always returns 1 for this item. It could be used in combination with nodata() for availability check.",
                        "valuemap": {
                            "name": "Zabbix agent ping status"
                        },
                        "request_method": "POST",
                        "tags": [
                            {
                                "tag": "Application",
                                "value": "Zabbix agent"
                            }
                        ],
                        "triggers": [
                            {
                                "uuid": "6d2a73199f3b4288bf36331a142c1725",
                                "expression": "nodata(/Template App Agent/agent.ping,5m)=1",
                                "name": "Zabbix agent on {HOST.NAME} is unreachable for 5 minutes",
                                "priority": "AVERAGE"
                            }
                        ]
                    },
                    {
                        "uuid": "2cc337555efd43d181c28c792f8cbbdb",
                        "name": "Version of zabbix_agent(d) running",
                        "key": "agent.version",
                        "delay": "1h",
                        "history": "1w",
                        "trends": "0",
                        "value_type": "CHAR",
                        "request_method": "POST",
                        "tags": [
                            {
                                "tag": "Application",
                                "value": "Zabbix agent"
                            }
                        ]
                    }
                ],
                "valuemaps": [
                    {
                        "uuid": "3d66c59a28c04b0ca8227c87902ddb4d",
                        "name": "Zabbix agent ping status",
                        "mappings": [
                            {
                                "value": "1",
                                "newvalue": "Up"
                            }
                        ]
                    }
                ]
            }
        ]
    }
}

CodePudding user response:

.zabbix_export.templates[] | .name as $tn | .items[] | [ $tn, .name, .triggers[]?.name? ] | join("; ")

  1. Loop over the templates
    .zabbix_export.templates[]
  2. Save the template name in a var
    .name as $tn
  3. Loop over the items
    .items[]
  4. Create an array with fields you like (including the name from step 1
    [ $tn, .name, .triggers[]?.name? ]
  5. Join the array to a string
    join("; ")

Will output:

"Template App Agent; Host name of zabbix_agentd running; Host name of zabbix_agentd was changed on {HOST.NAME}"
"Template App Agent; Agent ping; Zabbix agent on {HOST.NAME} is unreachable for 5 minutes"
"Template App Agent; Version of zabbix_agent(d) running"

Online demo

CodePudding user response:

This is a nested structure, you need to iterate level by level and add up the items you want to be in one output line. Store values from previous levels in variables.

To account for an inexistent .triggers array, you may use the Error Suppression Operator ? in combination with Alternative Operator //.

Finally, wrap the items in quotes (here using map), join them using join, and output them as raw text using the -r option

jq -r '
  .[].templates[] | .name as $t
  | .items[] | .name as $i
  | [$t, $i, (.triggers[].name)? // ""]
  | map("\"\(.)\"") | join("; ")
'
"Template App Agent"; "Host name of zabbix_agentd running"; "Host name of zabbix_agentd was changed on {HOST.NAME}"
"Template App Agent"; "Agent ping"; "Zabbix agent on {HOST.NAME} is unreachable for 5 minutes"
"Template App Agent"; "Version of zabbix_agent(d) running"; ""

Demo

Also consider using the @csv builtin, which gives you valid CSV right away (properly encoded (not just quoted) items, but separated with commas, not semicolons):

jq -r '
  .[].templates[] | .name as $t
  | .items[] | .name as $i
  | [$t, $i, (.triggers[].name)? // ""]
  | @csv
'
"Template App Agent","Host name of zabbix_agentd running","Host name of zabbix_agentd was changed on {HOST.NAME}"
"Template App Agent","Agent ping","Zabbix agent on {HOST.NAME} is unreachable for 5 minutes"
"Template App Agent","Version of zabbix_agent(d) running",""

Demo

  • Related