Як оновити одне значення в json-документі за допомогою jq?


104

Вибачення, якщо я пропустив щось дуже очевидне; Я щойно знайшов jqі намагаюся використовувати його для оновлення одного значення JSON, не впливаючи на навколишні дані.

Я хотів би конвеювати curlрезультат jq, оновити значення та конвеювати оновлений JSON до curl -X PUT. Щось на зразок

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

Поки що я зломлював це разом sed, але, переглянувши кілька прикладів |=оператора, jqя впевнений, що вони мені не потрібні.

Ось зразок JSON - як би я використовував jqдля встановлення "local": false, зберігаючи решту JSON?

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

Відповіді:


126

Ви встановлюєте значення об'єкта за допомогою =оператора. |=з іншого боку використовується для оновлення значення. Це тонка, але важлива різниця. Змінюється контекст фільтрів.

Оскільки ви встановлюєте для властивості постійне значення, використовуйте =оператор.

.shipping.local = false

Тільки зауважте, що при встановленні значення властивості воно не обов’язково повинно існувати. Ви можете легко додати нові значення таким чином.

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

10
Цей зразок не підходить для нормального значення. Отже, якщо вам потрібно змінити нормальне значення, вам потрібно додати "разом із ним, наприклад .shipping.local = "new place". Тож вся команда буде curl http://example.com/shipping.json | jq '.shipping.local = "new place"'. В іншому випадку ви отримаєте дивні помилки.
BMW

8
@BMW що? Тут чудово. Будь-яке дійсне значення json є дійсним, це просто буквене значення false. Значення не повинні бути рядками.
Джефф Меркадо,

@BMW ОП хоче встановити це за допомогою false. Що не так?
SOF,

17

Оновити значення (встановлює .foo.bar на "нове значення"):

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

Оновіть значення за допомогою змінної (встановлює .foo.bar на "привіт"):

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

Я використав це як приклад для перейменування NPM package.json через оболонку, і він працював на 100%, дякую.
Мачадо

2
Це насправді не замінює вміст файлу. Він друкує лише для видалення. Вам потрібно буде зберегти файл staout назад у файл, щоб зміни не зникли. Див stackoverflow.com/a/60744617/1626687
spuder

1

подібна функція до оператора | = є map. map підійде, щоб уникнути вимог попереднього фільтра для масиву ...

уявіть, що ваші дані - це масив (дуже поширений для цього прикладу)

[
  {
    "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": "$"
      }
    }
  }
]

отже, необхідно розглядати масив у коді як:

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

або використовувати функцію map, яка створена для роботи в кожному елементі масиву як

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

Спостереження

Заради тих, хто навчається, ви також зробили деякі помилки у використанні jq, просто врахуйте, що він "читає" 1-й параметр як програму, отже, всі бажані команди повинні бути включені в найперший рядок після виклику команди програма.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.