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

Файлы :

/config$ ls
166bbdd41c0297755ddb645db2b4c865  46a5c83d30483acba49a542a1ade9c33  87b2a640a5398156bf2d924b130ce42c  ca5b4cbc16a580cf5236097ec39e90e9

Структура JSON:

{
        "enabled": true,
        "services": [
                "933579ee8caafc4e818ddfe02ab58fdc"
        ],
        "tags": [
                "2a521880b86a0f043eb65cff37fac679",
                "b4fd044b9a7ab1146bb638ea42219b99"
        ],
        "bouquet": ""
}

Вопрос в том, как лучше добавить новый элемент в массив "services", если файл содержит значение "b4fd044b9a7ab1146bb638ea42219b99" в массиве "tags". Если этого значения нет в массиве «теги», пропустите файл, в противном случае добавьте «NEWVALUETOADD» в «services».

Если «NEWVALUETOADD» уже существует, мы также можем пропустить файл.

Пример вывода:

{
        "enabled": true,
        "services": [
                "NEWVALUETOADD"
                "933579ee8caafc4e818ddfe02ab58fdc"
        ],
        "tags": [
                "2a521880b86a0f043eb65cff37fac679",
                "b4fd044b9a7ab1146bb638ea42219b99"
        ],
        "bouquet": ""
}
1
Bohumír Mäsiar 19 Янв 2022 в 00:20

3 ответа

Сюда:

jq --arg nv "NEWVALUETOADD" 'select(.tags[] | select(. == "b4fd044b9a7ab1146bb638ea42219b99") ).services += [$nv]'

JQ-скрипт:

select(
  .tags[] | select(
    . == "b4fd044b9a7ab1146bb638ea42219b99"
  )
).services += [$nv]

jqplay.org с этим выше

1
Léa Gris 19 Янв 2022 в 00:45

Одним из вариантов будет использование индекса, чтобы найти точное совпадение с желаемым значением, а затем добавить новый элемент, например

jq '(select(.tags | index("b4fd044b9a7ab1146bb638ea42219b99")).services )+=["New Value"]' yourfile  

Демо

1
Barbaros Özhan 19 Янв 2022 в 00:57

Простой if … then … else … end может сделать:

jq --arg q "b4fd044b9a7ab1146bb638ea42219b99" --arg n "NEWVALUETOADD" '
  if IN(.tags[]; $q) and (IN(.services[]; $n) | not)
  then .services += [$n] else . end
'
{
  "enabled": true,
  "services": [
    "933579ee8caafc4e818ddfe02ab58fdc",
    "NEWVALUETOADD"
  ],
  "tags": [
    "2a521880b86a0f043eb65cff37fac679",
    "b4fd044b9a7ab1146bb638ea42219b99"
  ],
  "bouquet": ""
}

Демо

Чтобы затем перебрать каждый файл и изменить его, вам нужно использовать временные файлы, поскольку jq не имеет опции редактирования на месте (как sed делает с sed -i).

for file in *
do jq --arg q "b4fd044b9a7ab1146bb638ea42219b99" --arg n "NEWVALUETOADD" '
    if IN(.tags[]; $q) and (IN(.services[]; $n) | not)
    then .services += [$n] else . end
  ' "$file" > "$file.new" && mv "$file.new" "$file"
done
1
pmf 19 Янв 2022 в 01:25