Jq kullanarak bir json belgesindeki tek bir değeri nasıl güncellerim?


110

Çok bariz bir şeyi gözden kaçırdıysam özür dilerim; Az önce buldum jqve çevredeki verileri etkilemeden bir JSON değerini güncellemek için kullanmaya çalışıyorum.

Bir curlsonucu jqbir curl -X PUT. Gibi bir şey

curl http://example.com/shipping.json | jq '.' field: value | curl -X PUT http://example.com/shipping.json

Şimdiye kadar kullanarak birlikte hackledim sed, ancak |=operatörün birkaç örneğine baktıktan sonra jqbunlara ihtiyacım olmadığına eminim.

İşte bir JSON örneği - JSON'un geri kalanını korurken jqayarlamak için nasıl kullanırım "local": false?

{
  "shipping": {
    "local": true,
    "us": true,
    "us_rate": {
      "amount": "0.00",
      "currency": "USD",
      "symbol": "$"
    }
  }
}

Yanıtlar:


131

=Operatörü kullanarak bir nesnenin değerlerini ayarlarsınız . |=diğer yandan bir değeri güncellemek için kullanılır. Bu ince ama önemli bir fark. Filtrelerin bağlamı değişir.

Bir özelliği sabit bir değere ayarladığınız için =operatörü kullanın .

.shipping.local = false

Bir mülke değer belirlerken, var olması gerekmediğini unutmayın. Bu şekilde kolaylıkla yeni değerler ekleyebilirsiniz.

.shipping.local = false | .shipping.canada = false | .shipping.mexico = true

10
Bu örnek normal değer için iyi değildir. Dolayısıyla, normal değeri değiştirmeniz gerekirse, "bunun gibi eklemeniz gerekir .shipping.local = "new place". Böylece tüm komut olacak curl http://example.com/shipping.json | jq '.shipping.local = "new place"'. Aksi takdirde, garip hatalar alırsınız.
BMW

9
@BMW ne? Burada gayet iyi. Herhangi bir geçerli json değeri geçerlidir, bu sadece değişmezdir false. Değerlerin dizge olması gerekmez.
Jeff Mercado

@BMW OP ile ayarlamak istiyor false. Sorun nedir?
SOFe

.shipping.<INSERT VAR HERE>Jq'de VAR'ın nerede tanımlandığını nasıl ayarlarsınız ? Basit bir örnek olarak, jq --arg location local '.shipping.$location = false'çalışmasını sağlamak için nasıl değişiklik yapardınız ?
Max Murphy

1
@MaxMurphy:.shipping[$location] = false
Jeff Mercado

21

Bir değeri güncelleyin (.foo.bar'ı "yeni değer" olarak ayarlar):

jq '.foo.bar = "new value"' file.json

Değişken kullanarak bir değeri güncelleyin (.foo.bar'ı "merhaba" olarak ayarlar):

variable="hello"; jq --arg variable "$variable" '.foo.bar = $variable' file.json

Bunu örnek olarak bir NPM package.json'ı shell aracılığıyla yeniden adlandırmak için kullandım ve% 100 çalıştı, teşekkürler.
Machado

3
Bu aslında dosyanın içeriğini değiştirmez. Yalnızca standart çıktıya yazdırır. Değişikliğin kalıcı olması için dosyaya geri kaydetmeniz gerekecektir. Stackoverflow.com/a/60744617/1626687
spuder'a

3

| = operatörüne benzer bir işlev eşlemedir. harita, dizi için önceki bir filtre gerekliliğini ortadan kaldırmak için uygun olacaktır ...

verilerinizin bir dizi olduğunu düşünün (bu örnek için çok yaygındır)

[
  {
    "shipping": {
      "local": true,
      "us": true,
      "us_rate": {
        "amount": "1.00",
        "currency": "USD",
        "symbol": "$"
      }
    }
  },
  {
    "shipping": {
      "local": true,
      "us": true,
      "us_rate": {
        "amount": "1.00",
        "currency": "USD",
        "symbol": "$"
      }
    }
  }
]

bu nedenle koddaki diziyi şu şekilde düşünmek gerekir:

http://example.com/shipping.json | jq '.[] | .shipping.local = "new place"' | curl -X PUT http://example.com/shipping.json

veya her dizi öğesinde çalışacak şekilde hazırlanmış eşleme işlevini kullanmak için

http://example.com/shipping.json | jq 'map(.shipping.local = "new place")' | curl -X PUT http://example.com/shipping.json

Gözlem

Öğrenenler uğruna, jq kullanımında da bazı hatalar yaptınız, sadece program olarak 1. parametreyi "okuduğunu" düşünün, bu nedenle istenen tüm komutlar, çağrıldıktan sonra ilk dizeye dahil edilecektir. programı.


Bu neden zorunlu olarak farklıdır .[].shipping.local = "new place"?
roaima

1
Bu durumda fark, yanıttır, harita işlevini kullanmak bir dizi nesne verirken diğer seçeneğe, satır başına bir nesne dizisi vereceksiniz (bash olarak diğer yorumlayıcılara entegre etmek için kullanışlıdır)
Thiago Conrado
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.