Parsing JSON format with jq

I need to parse the output from lsblk. Since I am doing this from a script, I need the output in a standardized format. So I chose the JSON format as the output. Here is a command with some sample output:

# lsblk -o NAME,MOUNTPOINT -J
{
   "blockdevices": [
      {"name": "sda", "mountpoint": null,
         "children": [
            {"name": "sda1", "mountpoint": "/sda1/mountpoint"},
            {"name": "sda2", "mountpoint": null,
               "children": [
                  {"name": "sda2_mapper", "mountpoint": "/sda2/mountpoint"}
               ]
            },
            {"name": "sda3", "mountpoint": null},
            {"name": "sda4", "mountpoint": null}
         ]
      },
      {"name": "sdb", "mountpoint": null,
         "children": [
            {"name": "sdb1", "mountpoint": "/sdb1/mountpoint"},
            {"name": "sdb2", "mountpoint": null}
         ]
      },
      {"name": "sdc", "mountpoint": null}
   ]
}

I want to extract the names of all the innermost nodes, i.e. name of all nodes that do not have children. The desired output for the above sample would be:

sda1
sda2_mapper
sda3
sda4
sdb1
sdb2
sdc

My selection tool is jqone that I just recently discovered. I tried

# jq '.blockdevices[].children[]?.name?'

But it only filters the first level of names. I also tried using

# jq 'recurse(.name?)'

but this returns the whole file.

Is there a way to return only nodes that do not have children, no matter how deeply nested they are?

PS: bash awk. jq, json .

+4
2

, , , , :

$ jq -r '.blockdevices[] | .. | objects | select(has("children")|not)| .name' tmp.json
sda1
sda2_mapper
sda3
sda4
sdb1
sdb2
sdc

, JSON, , , children. , name .

+1

JSON :

jq '.. | scalars' 

"", :

"sda"
"sda1"
"/sda1/mountpoint"

-r (raw output), .

0

Source: https://habr.com/ru/post/1663776/


All Articles