Как использовать регулярное выражение для поиска ключа и значения и замены значения новым значением, используя jq - PullRequest
0 голосов
/ 23 мая 2019
My json
{
    "license": " See license.md",
    "dependencies": {
        "@gx/core": "0.279.0-b1-abc-1234-0716.4567",
        "@gx/api": "0.279.0-b1-abc-1234-0716.4567",
        "@gx/name": "0.279.0-b1-abc-1234-0716.4567"
    }
}

Я хочу заменить "0.279.0-b1-abc-1234-0716.4567" на "0.279.0-b1-abc-1234-0716.9856" во всех местах.

        jq '.dependencies[].["@gx/core"] |= (if . == "0.279.0-b1-abc-1234-0716.4567" then "0.279.0-b1-abc-1234-0716.9856" else . end)' info.json
jq: error: syntax error, unexpected '[', expecting FORMAT or QQSTRING_START (Unix shell quoting issues?) at <top-level>, line 1:
    .dependencies[].["@gx/core"] |= (if . == "0.279.0-b1-abc-1234-0716.4567" then "0.279.0-b1-abc-1234-0716.9856" else . end)                
    jq: 1 compile error   

I am looking for something like this
   jq '.dependencies[].["@gx/[a-z]*"] |= (if . == "^(\d+\.){2}[0-9]+(-[a-zA-Z0-9]*){4}\.[0-9]*$" then "0.279.0-b1-abc-1234-0716.9856" else . end)' info.json 

Ответы [ 2 ]

1 голос
/ 23 мая 2019

Используя jq, существует много разных подходов с очень разной семантикой, как видно из этих решений первой проблемы (без регулярных выражений):

walk(if . == "0.279.0-b1-abc-1234-0716.4567" 
     then "0.279.0-b1-abc-1234-0716.9856" else . end)

Более сфокусированный подход:

 .dependencies |=
   map_values(if . == "0.279.0-b1-abc-1234-0716.4567" 
              then "0.279.0-b1-abc-1234-0716.9856" else . end)

регулярные выражения

Все вышеперечисленные подходы можно использовать и в случае поиска регулярных выражений, например, последним случаем станет:

.dependencies |= with_entries(
  if (.key | test("@gx/[a-z]*"))
      and (.value | test("^(\\d+\\.){2}[0-9]+(-[a-zA-Z0-9]*){4}\\.[0-9]*$"))
  then .value = "0.279.0-b1-abc-1234-0716.9856" else . end)

Обратите внимание, что строки регулярных выражений должныбыть JSON-строками и, следовательно, удваивать обратную косую черту.

if без else

Если у вас достаточно свежая версия jq, эти висячие вхождения «else».можно бросить.

1 голос
/ 23 мая 2019

если вы рассматриваете решение, не относящееся к jq, позвольте мне предложить одно из них, основанное на утилите unix с обходом пути jtc:

bash $ <file.json jtc -w'[dependencies]<0\.279\.0\-b1\-abc\-1234\-0716\.4567>R:' -u'"0.279.0-b1-abc-1234-0716.9856"'
{
   "dependencies": {
      "@gx/api": "0.279.0-b1-abc-1234-0716.9856",
      "@gx/core": "0.279.0-b1-abc-1234-0716.9856",
      "@gx/name": "0.279.0-b1-abc-1234-0716.9856"
   },
   "license": " See license.md"
}
bash $ 

walk-path (-w):

  • [dependencies] адрес (от корня) указанной записи
  • <...>R: - лексема поиска, поиск с использованием RE (суффикс)R) все записи (квантификатор :), соответствующие данному выражению рег.

-u обновит (заменит) все найденные совпадения.

- или --

с использованием ваших RE, соответствующих обеим меткам и значениям:

bash $ <file.json jtc -w'[dependencies]<@gx/[a-z]*>L:<^(\d+\.){2}[0-9]+(-[a-zA-Z0-9]*){4}\.[0-9]*$>R' -u'"0.279.0-b1-abc-1234-0716.9856"'
  • тот же результат

PS> Раскрытие информации: я создательjtc инструмент

...