Пропуск нулевых значений для sub() в JQ

#json #jq

#json #jq

Вопрос:

Я пытаюсь изменить # значение # в каждом context значении, но у меня проблема с нулевыми значениями.

Сокращенный JSON:

 {
  "stats": {
    "suites": 1
  },
  "results": [
    {
      "uuid": "676-a46b-47a1-a49f-4da4e46c1120",
      "title": "",
      "suites": [
        {
          "uuid": "gghjh-56a9-4713-b139-0d5b36bc7fbc",
          "title": "Login process",
          "tests": [
            {
              "pass": false,
              "fail": true,
              "pending": false,
              "context": ""screenshots/login.spec.js/Login process -- should login #11 (failed).png""
            },
            {
              "pass": false,
              "fail": false,
              "pending": true,
              "context": null
            }
          ]
        }
      ]
    }
  ]
}
 

И команда JQ, я думаю, она ближе всего к правильной:

 jq '.results[].suites[].tests[].context | strings | sub("#";"#")'
 

Но проблема в том, что мне нужно получить взамен полностью отредактированный файл. Как я мог этого добиться?

Ответ №1:

Вы были близки. Чтобы сохранить исходную структуру, вам необходимо использовать оператор обновления ( |= ) вместо канала. Также необходимо заключить все выражение слева от него в круглые скобки, иначе исходный ввод будет невидимым для |= .

 (.results[].suites[].tests[].context | strings) |= sub("#"; "#")
 

Онлайн-демонстрация

Ответ №2:

измените # на # в каждом значении контекста

Возможно, вы захотите рассмотреть:

 walk( if type=="object" and (.context|type)=="string"
      then .context |= gsub("#"; "#")
      else . end )
 

Комментарии:

1. Есть ли какая-то разница между использованием walk и .. здесь? ( ( .. | select(type=="object" and (.context|type)=="string") | .context ) |= gsub("#"; "#") )

2. Не функционально.