JQ, применяющий функцию к dict, но печатающий окружающие данные

#jq

#jq

Вопрос:

Я бы хотел

 "1": {
        "id": "1",
        "type": "select",
        "label": "country :",
        "choices": {
          "1": {
            "label": "Canada CAN",
            "value": "",
          },
          "2": {
            "label": "United States USA",
            "value": ""
          }
        }
}
  

для получения

 "1": {
        "id": "1",
        "type": "select",
        "label": "country :",
        "choices": {
          "1": {
            "label": "Canada",
            "value": "CAN",
          },
          "2": {
            "label": "United States",
            "value": "USA"
          }
        }
}
  

К настоящему моменту у меня есть двухэтапное решение, состоящее из функции, подобной sed

 def do_extract:
if .value | test("^$") then
    (.value = (.label | capture(".* (?<code>...)")).code) | .label = (.label | capture("(?<name>.*) ...$").name)
else
    .
end;
  

и прямой доступ к поддереву []."1"."choices"|keys_unsorted as $key|map_values(do_extract) , но мне приходится вручную копировать-вставлять выходные данные вместо исходного dict «choices».

Есть ли способ выполнить функцию, но при этом распечатать окружающие данные?

Спасибо

Ответ №1:

Что ж, чтобы получить желаемый результат, вы могли бы сделать это:

 .[].choices[] |= (.label | capture("^(?<label>.*?) (?<value>[^ ] )$"))
  

Чтобы сделать это в вашей функции, я бы изменил ее на это:

 def do_extract:
  if .value == "" then
    (.label | capture("^(?<label>.*?) (?<value>[^ ] )$"))
  else
    .
  end;
  

Затем используйте его:

 .[].choices[] |= do_extract