เลือกวัตถุตามค่าของตัวแปรในวัตถุโดยใช้ jq


236

ฉันมีไฟล์ json ต่อไปนี้:

{
    "FOO": {
        "name": "Donald",
        "location": "Stockholm"
    },
    "BAR": {
        "name": "Walt",
        "location": "Stockholm"
    },
    "BAZ": {
        "name": "Jack",
        "location": "Whereever"
    }
}

ฉันใช้ jq และต้องการได้รับองค์ประกอบ "ชื่อ" ของวัตถุที่ 'ตำแหน่งที่ตั้ง' คือ 'สตอกโฮล์ม'

ฉันรู้ว่าฉันสามารถได้รับชื่อทั้งหมดด้วย

cat json | jq .[] | jq ."name"
"Jack"
"Walt"
"Donald"

แต่ฉันไม่สามารถหาวิธีพิมพ์เฉพาะวัตถุบางอย่างได้โดยระบุค่าของคีย์ย่อย (ที่นี่"location" : "Stockholm")

คำตอบ:


341

ดัดแปลงจากโพสต์นี้ในการประมวลผล JSON ด้วย jqคุณสามารถใช้สิ่งselect(bool)นี้:

$ jq '.[] | select(.location=="Stockholm")' json
{
  "location": "Stockholm",
  "name": "Walt"
}
{
  "location": "Stockholm",
  "name": "Donald"
}

30
ฉันจะได้ผู้ปกครอง 'FOO', 'BAR', 'BAZ' ได้อย่างไร
spazm

184

ในการรับสตรีมของชื่อ:

$ jq '.[] | select(.location=="Stockholm") | .name' json

ผลิต:

"Donald"
"Walt"

ในการรับสตรีมของคู่ (ชื่อคีย์, ชื่อ "แอตทริบิวต์") ให้พิจารณา:

$ jq -c 'to_entries[]
        | select (.value.location == "Stockholm")
        | [.key, .value.name]' json

เอาท์พุท:

["FOO","Donald"]
["BAR","Walt"]

เขาต้องการให้วัตถุทั้งหมดขึ้นอยู่กับสถานที่: "ฉันไม่สามารถหาวิธีพิมพ์เฉพาะวัตถุบางอย่างที่ให้ค่าของคีย์ย่อย"
Fo

2
คุณไม่ต้องการไพพ์หลังจากเลือก: $ jq '. [] | เลือก (.location == "Stockholm") ชื่อ 'json
Deepak

ทำให้nameตัวแปรสำคัญ (ใช้ฟังก์ชั่นเปลือก$1เป็นพารามิเตอร์) termux-contact-list |jq -r '.[] | select(.name=="$1")|.number'ไม่ทำงาน: cool_fn Name1ผมเรียกมันเหมือน อย่างไรก็ตามการทำงานนี้:termux-contact-list |jq -r '.[] | select(.name=="Name1")|.number'
Timo

นี่คือทางออกถ้าคุณชอบมันตัวแปร
Timo

27

ฉันมีคำถามที่เกี่ยวข้องคล้ายกัน: ถ้าคุณต้องการรูปแบบวัตถุต้นฉบับกลับมา (ด้วยชื่อคีย์เช่น FOO, BAR)

Jq ให้to_entriesและfrom_entriesการแปลงระหว่างวัตถุและอาร์เรย์คู่ค่าคีย์ ที่มาพร้อมกับmapรอบ ๆ ตัวเลือก

ฟังก์ชั่นเหล่านี้แปลงระหว่างวัตถุและอาร์เรย์ของคู่ค่าคีย์ หาก to_entries ผ่านวัตถุดังนั้นสำหรับแต่ละรายการ k: v ในอินพุตอาร์เรย์เอาต์พุตประกอบด้วย {"key": k, "value": v}

from_entries ทำการแปลงตรงกันข้ามและ with_entries (foo) เป็นชวเลขสำหรับ to_entries | แผนที่ (foo) | from_entries มีประโยชน์สำหรับการดำเนินการบางอย่างกับคีย์และค่าทั้งหมดของวัตถุ from_entries รับคีย์, คีย์, ชื่อ, ชื่อ, มูลค่าและมูลค่าเป็นกุญแจ

jq15 < json 'to_entries | map(select(.value.location=="Stockholm")) | from_entries'

{
  "FOO": {
    "name": "Donald",
    "location": "Stockholm"
  },
  "BAR": {
    "name": "Walt",
    "location": "Stockholm"
  }
}

การใช้with_entriesชวเลขนี้จะกลายเป็น:

jq15 < json 'with_entries(select(.value.location=="Stockholm"))'
{
  "FOO": {
    "name": "Donald",
    "location": "Stockholm"
  },
  "BAR": {
    "name": "Walt",
    "location": "Stockholm"
  }
}

1
สิ่งหนึ่งที่ยังคงกัดฉันอยู่คือคุณต้องจำไว้ว่าเมื่อใช้with_entries()คุณมักจะต้องการใช้.valueในselectข้อ เพราะนี่คือto_entriesแมโครแปลงรายการรับไป.keyและคู่ซึ่งยังเกิดขึ้นกับ.value with_entries
Jaakko
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.