簡體   English   中英

使用jq解析JSON格式

[英]Parsing JSON format with jq

我需要解析lsblk的輸出。 由於我是在腳本中執行此操作,因此需要以標准格式輸出。 因此我選擇JSON格式作為輸出。 這是帶有一些示例輸出的命令:

# 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}
   ]
}

我想提取所有最內層節點的名稱,即所有沒有子節點的節點的名稱。 上述樣本的所需輸出為:

sda1
sda2_mapper
sda3
sda4
sdb1
sdb2
sdc

我選擇的工具是jq ,我最近才發現它。 我試過了

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

但這只會過濾第一級別的名稱。 我也嘗試過

# jq 'recurse(.name?)'

但這會返回整個文件。

有沒有辦法只返回沒有子節點的節點,無論它們嵌套多深?

PS:我能夠在bashawk中實現這個要求。 但是,我更喜歡使用像jq這樣的工具的解決方案,其具體目的是解析json文件。

我不認為這是最簡單的方法,但似乎有效:

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

它遞歸地輸出在JSON中找到的每個值,首先篩選出不是對象的任何內容,然后篩選出具有children鍵的任何對象。 最后,您可以從每個剩余對象中選擇name值。

使用您的JSON輸入,以下命令:

jq '.. | scalars' 

發出“葉子”,開頭:

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

使用-r(原始輸出)從字符串中去除引號。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM