Я совершенно новый (стажер с практическим опытом менее двух недель) в BASH, JSON и jq. Но мне была дана задача итеративно заменить значение объекта JSON из массива. Мне удалось написать следующий код.
Я пытаюсь постепенно заменять значения ключа «имя» в файле json на имена в массиве, хранящемся в другом текстовом файле. По сути, просто обновляем имена узлов.
Вот фрагмент файла JSON, который нужно заменить. Весь файл слишком велик для размещения здесь.
Но путь к ключу «имя» - это «.lab.racks []. Node []. Name»
"roles": [
"bla bla",
"bla bla"
],
"name": "Node1",
"power": {
"address": "10.182.149.145",
"type": "bla bla",
"user": "bla bla",
"pass": "bla bla "
},
«name»: «Node1» необходимо заменить на «name»: «Tom-cat». Имя Tom-cat генерируется динамически и изменяется каждый раз, когда запускается скрипт Metal as a Service (MaaS). Это имя "Tom-cat" и все другие новые имена, сгенерированные MaaS, вырезаны (с использованием awk) и сохранены в текстовом файле newhostnames.txt
Текстовый файл выглядит так
#newhostnames.txt
Tom-cat
Lucky-worm
Wom-bat
Таким образом, цель состоит в том, чтобы заменить ключ "name" из demolabconfig.json именами, хранящимися в текстовом файле.
"name": "Node1" must be replaced as "name":"Tom-cat"
];
.....
.....
],
"name": "Node2" must be replaced as "name":"Lucky-worm"
];
.....
.....
],
"name": "Node3" must be replaced as "name":"Wom-bat"
Индексация выполняется для ключевых «узлов»: .lab.racks []. Node [$ i] .name
код:
readarray -t array < newhostnames.txt
array=("${array[@]:1}")
array_length=${#array[@]}
for((i=0;i<${array_length};i++));
do
declare -x NEW_NODENAME
OLD_NODENAME=$(jq -r ".lab.racks[].nodes[$i].name" demolabconfig.json)
echo "$OLD_NODENAME"
NEW_NODENAME="${array[i]}"
echo "$NEW_NODENAME"
jq ".lab.racks[].nodes[$i].name=env.NEW_NODENAME" demolabconfig.json > newdemolabconfig.json
done
Но код заменяет только одно значение в конце для последней $ i, т.е. последней пары key_value. Все остальные предыдущие узлы сохраняют то же имя, что и в исходном файле JSON.
Я попытался с помощью оператора if разорвать цикл, если значение уже обновлено, поэтому оно не перезаписано из старого файла demolabconfig.json. Но это тоже не работает!
if [[ "$OLD_NODENAME" -ne "$NEWNODENAME" ]]; then
jq ".lab.racks[].nodes[$i].name=env.NEW_NODENAME" demolabconfig.json > newdemolabconfig.json
else
break
fi
Это если цикл был написан с циклом while вместо for. Это заменяет фамилию на ноль.
Подскажите, пожалуйста, как я могу исправить эту ошибку и улучшить свой код. Спасибо:)