Я пытаюсь заменить токены в файле JSON значениями, хранящимися в нашем инструменте непрерывной интеграции (Bamboo).
Для этого я jq
извлекаю массив values
, а затем заменяю токен в каждом значении соответствующим ему значением переменной Bamboo.
Однако что-то не работает. Вывод на скрипте подтверждает, что токен замены находится, и что значение переменной Bamboo верно.
Что я делаю не так?
ENV_FILE_PATH="./landmark-accounts-uat.postman_environment.json"
VALUES=$(cat ./landmark-accounts-uat.postman_environment.json | jq -c '.values[]')
for ELEMENT in $VALUES; do
### Extract the variable name and replacement token (e.g. '#{varName}') for the current element.
ELEMENT_NAME=$(echo $ELEMENT | jq -r '.key')
ELEMENT_REPLACEMENT_TOKEN=$(echo $ELEMENT | jq -r '.value')
### Construct the name of the Bamboo variable to use for replacement.
BAMBOO_VARIABLE_NAME=bamboo\_$ELEMENT_NAME
BAMBOO_VARIABLE_VALUE=${!BAMBOO_VARIABLE_NAME}
### Replace the current value with the value of the Bamboo variable.
echo "Replacing '$ELEMENT_REPLACEMENT_TOKEN' with the value of Bamboo variable '$BAMBOO_VARIABLE_NAME' ($BAMBOO_VARIABLE_VALUE)."
sed -i 's/$ELEMENT_REPLACEMENT_TOKEN/$BAMBOO_VARIABLE_VALUE/g' $ENV_FILE_PATH
done
Пример файла JSON
Ниже приведен пример файла JSON до его редактирования с помощью sed
.
Как вы видите, есть токены замены для каждого value
, и именно их я пытаюсь заменить переменными Bamboo. В этом случае эти переменные будут называться $bamboo_apiUrl
и $bamboo_apimKey
.
{
"id": "b10a67a9-75a1-49fc-8b6d-9063388ed35c",
"name": "my-env",
"values": [
{
"key": "apiUrl",
"value": "#{apiUrl}",
"enabled": true
},
{
"key": "apimKey",
"value": "#{apimKey}",
"enabled": true
},
],
"_postman_variable_scope": "environment",
"_postman_exported_at": "2019-09-27T09:13:43.208Z",
"_postman_exported_using": "Postman/7.8.0"
}
Обновлять
Основываясь на предложении в комментариях, я использую именно это решение.
#!/bin/bash
### Read in the environment file in full.
ENV_FILE_PATH="./landmark-accounts-uat.postman_environment.json"
ENVIRONMENT_FILE=$(cat $ENV_FILE_PATH)
### Get all of the value keys from the environment file.
KEYS=$(cat $ENV_FILE_PATH | jq --raw-output '.values[].key')
### Iterate value keys...
for KEY in $KEYS; do
### Construct the name of the Bamboo variable to use for 'value' for the current 'key', then get the value of that variable.
BAMBOO_VARIABLE_NAME=bamboo\_$KEY
BAMBOO_VARIABLE_VALUE=${!BAMBOO_VARIABLE_NAME}
### Replace the value for the currently 'key'.
echo "Replacing value of key '$KEY' with the value of Bamboo variable '$BAMBOO_VARIABLE_NAME' ($BAMBOO_VARIABLE_VALUE)."
ENVIRONMENT_FILE=$(echo $ENVIRONMENT_FILE | jq --arg key "$KEY" --arg value "$BAMBOO_VARIABLE_VALUE" '.values |= map(if .key == $key then .value = $value else . end)')
done
### Output the updated environment file.
echo $ENVIRONMENT_FILE > $ENV_FILE_PATH
решение1
Вы заключили переменные в одинарные кавычки, но:
Заключение символов в одинарные кавычки сохраняет буквальное значение каждого символа внутри кавычек.
Вам это не нужно, вы хотите, $
чтобы оболочка имела особое значение для оценки переменных. Поэтому используйте вместо этого двойные кавычки:
sed -i "s/$ELEMENT_REPLACEMENT_TOKEN/$BAMBOO_VARIABLE_VALUE/g" $ENV_FILE_PATH
На самом деле, ни «s», ни «/», ни «g»требуеткавычки, поэтому в зависимости от содержимого переменной вы можете даже оставить все выражение без кавычек. Однако всегда рекомендуется заключать переменные в кавычки.
Вы можете легко проверить эффект вашего кавычек, добавив в начало echo
, просто добавьте эти две строки и сравните вывод:
echo sed -i 's/$ELEMENT_REPLACEMENT_TOKEN/$BAMBOO_VARIABLE_VALUE/g' $ENV_FILE_PATH
echo sed -i "s/$ELEMENT_REPLACEMENT_TOKEN/$BAMBOO_VARIABLE_VALUE/g" $ENV_FILE_PATH
дальнейшее чтение
- (мое) объяснение механизмов цитирования
man bash
/ЦИТАТА(цитата оттуда)