簡體   English   中英

匹配JSON文本中的鍵值模式並獲取另一個鍵的值

[英]Match a key-value pattern in JSON text and get the value for another key

假設我有一個帶有此JSON的文件:

[
   {
      "label" : "deploy",
      "pk" : 2388175,
      "key" : "gsfd45"
   },
   {
      "label" : "jenkins",
      "key" : "eQtIAwP",
      "pk" : 2388165
   }
]

我想獲取鍵“ pk”的值,如果它在具有label =“ deploy”的哈希中。

我怎樣才能做到這一點? 我需要寫腳本嗎?

要在Bash中解析JSON,請使用jq

$ jq '.[] | select(.label=="deploy").pk' file
2388175

如果要將deploy存儲在一個變量中,請使用--arg jq手冊→調用jq

--arg名稱值

此選項將值作為預定義變量傳遞給jq程序。 如果使用--arg foo bar運行jq,則$ foo在程序中可用,並且值為“ bar”。 請注意,值將被視為字符串,因此--arg foo 123會將$ foo綁定到“ 123”。

$ v="deploy"
$ jq --arg var "$v" '.[] | select(.label==$var).pk' file
2388175

$ v="blabla"
$ jq --arg var "$v" '.[] | select(.label==$var).pk' file
            # empty!

$ v="jenkins"
$ jq --arg var "$v" '.[] | select(.label==$var).pk' file
2388165

按件:

打印所有內容:

$ jq '.[]' file
{
  "key": "gsfd45",
  "pk": 2388175,
  "label": "deploy"
}
{
  "pk": 2388165,
  "key": "eQtIAwP",
  "label": "jenkins"
}

打印label等於“ deploy”的記錄:

$ jq '.[] | select(.label=="deploy")' file
{
  "key": "gsfd45",
  "pk": 2388175,
  "label": "deploy"
}

在這種情況下,只打印字段pk

$ jq '.[] | select(.label=="deploy").pk' file
2388175

如果您的服務器上沒有jq,則python應該在那里,對嗎? ^ _ *

#!/bin/python
import json
with open('data.json') as data_file:    
    data = json.load(data_file)
    for d in data:
        if d['label'] == 'deploy':
            print(d["pk"])

假定名為data.json的文件另存為id.py ,並運行:

python id.py

它需要在系統上安裝python3

如果僅安裝了python2,則將行print (d["pk"])更改為print d["pk"]

輸出為:

2388175

編輯

添加了if檢查,沒有注意到OP要檢查label

在awk。 這有點不完整,但是由於您沒有任何要顯示的內容,因此可以進行以下操作:

$ awk -F: '$1~/"label"/{l=$2} l~/deploy/ && $1 ~ /pk/ {sub(/,/,"",$2);print $2}' file
 2388175

當awk遇到上面帶有"label"的記錄時,它將存儲$2 一旦找到pk並在其中deploy了標記l ,請刪除逗號並打印。

如果James Brown提供的優雅解決方案不起作用(例如,鍵/值對的不同順序),則是嘗試至少將大括號之間的字符串合並為一個記錄(通過設置RS ),然后將字符串拆分在具有鍵“ pk”的鍵值對中(通過設置FS )。

完成該設置后,模式將在$ 0中查找標簽/部署鍵/值對,然后,僅當有兩個字段(例如pk存在且發生字段拆分)時,才會刪除$ 2中逗號后的字符串,並密鑰pk的值保留並打印:

script.awk

BEGIN {
    RS="[{}[\\]]"
    FS="\"pk\"[^:]*:"
    }

/"label"[^:]*:[^\"]*"deploy"/ {
        if( NF == 2 ) { 
            # "pk" is present in $0, remove everything after comma
            sub(/,.*/, "", $2)
            print $2
        }
    }

您可以將以下腳本與awk一起使用: awk -f script.awk yourfile

我只在GNU awk上進行過嘗試,但是RSFS也應在awk上運行。

暫無
暫無

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

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