Вставить переменную bash в json с помощью jq

Я пытаюсь заполнить шаблон JSON с увеличивающимся счетчиком для создания огромного набора данных выборки:

#!/bin/bash
for ((counter=1 ; counter<2 ;counter++ ))
do
  NUMBER=${counter}
  JSON=$(cat template.json | jq --arg NUMBER "$NUMBER" '.')
  echo $JSON
  #aws dynamodb batch-write-item --request-items "${JSON}"
done

Мой template.json выглядит так:

{
"My_Table":[{
    "PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_A"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_A"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_A"},"name":{ ...        
    "PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_B"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_B"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_B"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_C"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_C"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_D"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_E"},"name":{ ...
}]

}

Могу ли я получить подсказку, как вставить переменную bash в шаблон JSON? Думаю, здесь я неправильно использую jq:

JSON=$(cat template.json | jq --arg NUMBER "$NUMBER" '.')

РЕДАКТИРОВАТЬ Мой желаемый результат:

{
"My_Table":[{
    "PutRequest":{"Item":{"type":{"S":"test-1-Type_A"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-1-Type_A"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-1-Type_A"},"name":{ ...        
    "PutRequest":{"Item":{"type":{"S":"test-1-Type_B"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-1-Type_B"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-1-Type_B"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-1-Type_C"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-1-Type_C"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-1-Type_D"},"name":{ ...
    "PutRequest":{"Item":{"type":{"S":"test-1-Type_E"},"name":{ ...
}]

}

Куда вы хотите вставить номер в данном JSON

Inian 10.09.2018 09:16

Пожалуйста, добавьте желаемый результат для этого образца ввода к вашему вопросу.

Cyrus 10.09.2018 09:17

@Inian хочет заменить $NUMBER на counter

RNA 10.09.2018 09:21

@Cyrus, добавлен желаемый результат

RNA 10.09.2018 09:22
1
4
213
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

К сожалению, есть несколько частей вопроса, которые не совсем понятны, но я считаю, что следующее должно помочь вам.

Во-первых, я предполагаю, что ваш шаблон является действительным JSON:

{
    "My_Table": [
    {"PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_A"},"name":0}}},
    {"PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_A"},"name":1}}},
    {"PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_A"},"name":2}}},
    {"PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_B"},"name":0}}},
    {"PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_B"},"name":1}}},
    {"PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_B"},"name":2}}},
    {"PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_C"},"name":0}}},
    {"PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_D"},"name":1}}},
    {"PutRequest":{"Item":{"type":{"S":"test-$NUMBER-Type_E"},"name":0}}}
  ]
}

Во-вторых, я предполагаю, что вы хотите, чтобы результат соответствовал показанному, а не описанному, но следующее написано так, чтобы вы могли легко адаптировать код к описанной проблеме. В частности, функциональность для выполнения замены инкапсулирована в следующем определении:

def resolve(s; value):
  .My_Table |= map(.PutRequest.Item.type.S |= 
     sub("-" + s + "-"; "-" + (value|tostring) + "-" ));

Это написано с использованием sub, первым аргументом которого должно быть регулярное выражение. Итак, чтобы сгенерировать желаемый результат для единственной замены «ЧИСЛО $» на «1», нужно написать:

resolve("\\$NUMBER"; 1)

Поскольку я не уверен, что именно должен делать ваш фрагмент bash, я просто предлагаю вам использовать итерацию в jq для достижения любого результата, который вам нужен, вместо использования итерации bash.

Ответ принят как подходящий

Если шаблон предназначен для использования с jq, его следует изменить для правильной работы, а не пытаться заставить jq работать с нестандартным вводом.

{
    "My_Table":[{
        "PutRequest":{"Item":{"type":{"S":"test-\($NUMBER)-Type_A"},"name":{ ...
        "PutRequest":{"Item":{"type":{"S":"test-\($NUMBER)-Type_A"},"name":{ ...
        "PutRequest":{"Item":{"type":{"S":"test-\($NUMBER)-Type_A"},"name":{ ...        
        "PutRequest":{"Item":{"type":{"S":"test-\($NUMBER)-Type_B"},"name":{ ...
        "PutRequest":{"Item":{"type":{"S":"test-\($NUMBER)-Type_B"},"name":{ ...
        "PutRequest":{"Item":{"type":{"S":"test-\($NUMBER)-Type_B"},"name":{ ...
        "PutRequest":{"Item":{"type":{"S":"test-\($NUMBER)-Type_C"},"name":{ ...
        "PutRequest":{"Item":{"type":{"S":"test-\($NUMBER)-Type_C"},"name":{ ...
        "PutRequest":{"Item":{"type":{"S":"test-\($NUMBER)-Type_D"},"name":{ ...
        "PutRequest":{"Item":{"type":{"S":"test-\($NUMBER)-Type_E"},"name":{ ...
    }]
}

Теперь что-то вроде вашей первоначальной попытки будет работать правильно. (Назовите свой шаблон template.jq, чтобы подчеркнуть, что он на самом деле недействительный JSON.)

for ((counter=1 ; counter<2 ;counter++ ))
do
  JSON=$(jq -n -f template.jq --arg NUMBER "$counter")
  echo "$JSON"
  #aws dynamodb batch-write-item --request-items "${JSON}"
done

Другие вопросы по теме

Неопределенные символы для архитектуры x86_64: "std :: __ 1 :: locale :: use_facet (std :: __ 1 :: locale :: id &) const"
Извлечь подстроку из строки после третьего последнего символа подчеркивания
Bash: чтение отбрасывает ввод линии терминала после 4096 байт
Сценарий sudo на bash без запроса пароля - установка manjaro nfs
Устранение повторяющихся строк на основе двух столбцов с помощью awk
Cygwin и linux - получить текущего пользователя, если $ user не установлен
Как добавить пробел после запятой, если его нет в 6-м столбце файла csv?
Переименовать файлы, начинающиеся с цифр, на две цифры
Как использовать sed, cut или awk, чтобы глобально обрезать 10-й столбец до 30 символов, но пропуская заголовок, а затем добавить пробел плюс 3 точки?
Я хочу добавить условие if в цикл while, чтобы проверить одну и ту же строку в каждой строке в 2 файлах и распечатать другие столбцы в файлах, если они совпадают