Скрипт jq: объединить содержимое итерации в тело json - PullRequest
0 голосов
/ 02 июля 2018

Я создаю сценарий оболочки.

Мне нужно создать curl json body в соответствии с содержимым списка key-value. Это содержимое разделяется на awk, который генерирует таблицу из двух столбцов:

KVS_VARIABLES=$(awk -F= '!($1 && $2 && NF==2) { print "File failed validation on line " NR | "cat 1>&2"; next } { print $1, $2 }' $f)

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

VAR1 VAL1
VAR2 VAL2
VAR3 VAL3

Итак, эта таблица повторяется на некоторой итерации, и каждый key и value делятся:

echo "$KVS_VARIABLES" | while read -r kv
  do
    key=$(echo $kv | awk '{print $1}')
    value=$(echo $kv | awk '{print $2}')
  done

Итак, мне нужен какой-то способ объединить этот контент в документ json, чтобы отправить его, используя curl:

curl -k \
  -X PUT \
  -d @- \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  "$SERVER_URL/api/v1/namespaces/$NAMESPACE/secrets/$SECRET_ID" <<-EOF
  {
    "kind": "Secret",
    "apiVersion": "v1",
    "metadata": {
      "name": "$SECRET_ID"
    },
    "stringData": {
      "$key": "$value"     <<<<<<<<<<<<<(1)>>>>>>>>>>>>>>
    }
  }
EOF

Итак, на <<<<<<<<<<<<<(1)>>>>>>>>>>>>>> мне нужно агрегировать каждое key и value распространение.

Итак, в этом случае мне нужно сгенерировать:

"VAR1": "VAL1",
"VAR2": "VAL2",
"VAR3": "VAL3"

, а затем вставьте его внутри "stringData":

{
    "kind": "Secret",
    "apiVersion": "v1",
    "metadata": {
      "name": "$SECRET_ID"
    },
    "stringData": {
       <<<<<<<<<<<<<(1)>>>>>>>>>>>>>>
    }
}

Итак, в конце концов:

{
    "kind": "Secret",
    "apiVersion": "v1",
    "metadata": {
      "name": "$SECRET_ID"
    },
    "stringData": {
       "VAR1": "VAL1",
       "VAR2": "VAL2",
       "VAR3": "VAL3"
    }
}

jq установлено.

Есть идеи?

1 Ответ

0 голосов
/ 02 июля 2018

Вы не нуждаетесь в операторе awk внутри цикла while, а просто читаете пары ключ-значение внутри самой команды read.

Также сохранение awk выходных данных в переменной и последующий анализ - это анти-паттерн. Вы можете использовать функцию подстановки процесса, предоставляемую оболочкой, часть < <() будет отбрасывать вывод команды, как если бы она появлялась в файле (или) использовать строки здесь

json=$(cat <<-EOF
{
    "kind": "Secret",
    "apiVersion": "v1",
    "metadata": {
      "name": "$SECRET_ID"
    },
    "stringData": {
    }
}
EOF
)

while read -r key value; do
    json=$(echo "$json" | jq ".stringData += { \"$key\" : \"$value\" }")
done< <(awk -F= '!($1 && $2 && NF==2) { print "File failed validation on line " NR | "cat 1>&2"; next } { print $1, $2 }' $f)

Теперь вы можете использовать переменную "$json" в curl как

curl -k \
  -X PUT \
  -d @- \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  "$SERVER_URL/api/v1/namespaces/$NAMESPACE/secrets/$SECRET_ID" <<<"$json"
...