Как использовать jq для объединения файлов как json, где имя файла - это селектор свойств, а содержимое файла - это значение? - PullRequest
1 голос
/ 08 ноября 2019

Я использую jq для выполнения некоторых манипуляций с json. Сценарий состоит в том, что у меня есть файл json и ряд других файлов, которые содержат либо json, либо строки, и я хочу объединить их в один вывод.

main.json содержит:

{
  "property1": "someValue",
  "sub": {
     "property2": "property2"
   }
}

.property1 (это имя файла) содержит:

newValue

.sub.property2 (это имя файла) содержит:

newProperty2

.other (это имя файла) содержит:

{
  "complex": {
    "cprop": "cpropvalue"
  }
}

Я хочу объединить эти файлы, используя имя файла в качестве селектора jq и содержимое файла в качестве значения. Вывод этого будет:

{
  "property1": "newValue",
  "sub": {
     "property2": "newProperty2"
   },
   "other": {
      "complex": {
        "cprop": "cpropvalue"
      }
   }
}

Вариант использования: у меня есть несколько пар ключ / значение (например, env vars), которые я хочу объединить общим способом в файл конфигурации json,

Инструмент jq очень мощный, но мне трудно понять, как это сделать. Если последний сценарий (содержимое файла - json) невозможен, первые два все еще чрезвычайно полезны. Основываясь на других поисках, я думаю, что все части есть (имя файла, входные данные и т. Д.), Но я выясняю, как их объединить.

1 Ответ

3 голосов
/ 08 ноября 2019

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

jq '
  def props: 
    split(".") | map(select(length>0));

  reduce inputs as $json (.;
    setpath(input_filename | props; $json) )
' main.json .other .property1 .sub.property2 

Точечные файлы могут быть перечислены в любом порядке (например, возможно .???*),но должен быть указан после main.json.

Основная тонкость здесь заключается в том, что первые ., которые появляются после reduce, будут заполнены содержимым main.json.

Toиспользуйте описанный выше подход для решения проблемы, как указано, необходимо преобразовать необработанный текст в файлах с именами .property1 и .sub.property2 в допустимый JSON. Это можно сделать на этапе предварительной обработки, например, следующим образом:

jq -R .property1 | sponge .property1
jq -R .sub.property2 | sponge .sub.property2

Не стесняйтесь выбирать любую из множества других альтернатив и вариантов :-)

...