Jq kullanarak nesnedeki değişkenin değerine göre nesneleri seçme


236

Aşağıdaki json dosyası var:

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

Jq kullanıyorum ve 'konum' 'Stockholm' olduğu nesnelerin "ad" öğelerini almak istiyorum.

Tüm isimleri alabileceğimi biliyorum

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

Ancak, bir alt anahtarın değeri göz önüne alındığında, yalnızca belirli nesnelerin nasıl yazdırılacağını anlayamıyorum (burada "location" : "Stockholm").

Yanıtlar:


341

JQ ile JSON İşleme konusundaki bu yayından uyarlanmış olarak aşağıdakini kullanabilirsiniz select(bool):

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

30
Ebeveyne 'FOO', 'BAR', 'BAZ' nasıl edinebilirim?
spazm

184

Yalnızca adlardan oluşan bir akış elde etmek için:

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

üretir:

"Donald"
"Walt"

Karşılık gelen (anahtar adı, "ad" özniteliği) çift akışını elde etmek için şunları göz önünde bulundurun:

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

Çıktı:

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

Tüm nesneyi konuma göre istiyor: "Bir alt anahtarın değeri göz önüne alındığında, yalnızca belirli nesnelerin nasıl yazdırılacağını
anlayamıyorum

2
Seçimden sonra boruya ihtiyacınız yoktur: $ jq '. [] | (.location == "Stockholm") adını seçin. 'json
Deepak

Yapımı name(bir kabuk işlevini kullanın anahtar değişken $1parametre olarak) çalışma değildir: termux-contact-list |jq -r '.[] | select(.name=="$1")|.number'. Buna şöyle diyorum cool_fn Name1. Ancak, bu çalışır:termux-contact-list |jq -r '.[] | select(.name=="Name1")|.number'
Timo

Değişken hoşunuza giderse çözüm İşte .
Timo

27

Benzer bir ilgili sorum vardı: Orijinal nesne biçimini geri isteseydiniz (anahtar isimleriyle, örneğin FOO, BAR)?

Jq sağlar to_entriesve from_entriesnesneler ve anahtar / değer çifti dizileri arasında dönüştürme. Bu mapseçim etrafında ile birlikte

Bu işlevler bir nesne ile bir dizi anahtar / değer çifti arasında dönüştürme yapar. To_entries bir nesneden geçirilirse, girişteki her k: v girişi için çıkış dizisi {"anahtar": k, "değer": v} içerir.

from_entries ters dönüştürme yapar ve with_entries (foo) to_entries için bir kısayol | haritası (foo) | from_entries, bir nesnenin tüm anahtarlarına ve değerlerine işlem yapmak için kullanışlıdır. from_entries anahtar, Anahtar, ad, Ad, değer ve Değeri anahtar olarak kabul eder.

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

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

with_entriesStenografi kullanarak , bu olur:

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

1
Beni ısırıyor tutar Bir şey kullanırken hatırlamak gerekir ki with_entries(), genellikle de kullanmak istiyorum .valueiçinde selectmaddesi. Bunun nedeni, to_entriesmakronun verilen girdileri .keyve .valueeşleşmeye dönüştürmesidir with_entries.
Jaakko
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.