У меня есть файл JSON под названием data.json со следующим содержимым:
{
"A": "10",
"BB": {
"m": "refresh",
"t": 1100,
"tt": 1,
"pp": 0,
"fp": 0
},
"ss": "1",
"ZZZ": {
"0": {
"np": 45,
"sh": "True",
"ni": 32,
"ft": "False",
"te": "True",
"t": 23,
"mm": 21
}
},
"nr": "564"
}
Я хочу иметь скрипт bash, который выполняет следующую задачу. Существует цикл for от i = 1 до 100 итераций. В первой итерации только 0 в значении «ZZZ» следует изменить на значение i, равное 1. Новое содержимое должно быть записано в data.json. Во второй итерации содержимое data.json считывается, и только 1 в значении «ZZZ» следует изменить на значение i, которое сейчас равно 2, и новое содержимое должно быть записано в data.json. Этот процесс выполняется до конца цикла. У меня есть следующий скрипт:
#!/bin/bash
# Input JSON file and output directory
input_file = "data.json"
# Loop from i=1 to 100
for ((i=1; i<=100; i++)); do
# Copy the original JSON to a new file
cp "$input_file" "output.json"
# Modify the JSON file with jq
jq --argjson new_i "$i" '.ZZZ[$new_i] = .ZZZ[$i - 1] | del(.ZZZ[$i - 1])' "output.json" > "temp.json"
# Move the modified JSON back to the original file
mv "temp.json" "data.json"
done
Когда я запускаю скрипт, я получаю следующую ошибку:
jq: 2 compile errors
jq: error: $i is not defined at <top-level>, line 1:
.ZZZ[$new_i] = .ZZZ[$i - 1] | del(.ZZZ[$i - 1])
У меня вопрос: как исправить ошибку?
Спасибо.





Один из способов достижения того, что вы ищете, заключается в следующем:
#!/bin/bash
for ((i=1; i<=100; i++)); do
jq '.ZZZ = {
'\"$i\"': {
"np": 45,
"sh": "True",
"ni": 32,
"ft": "False",
"te": "True",
"t": 23,
"mm": 21
}
}' "data.json" > "temp.json"
mv "temp.json" "data.json"
done
Если вы хотите, чтобы после каждой записи были отдельные файлы, вы можете изменить mv "temp.json" "data.json" на mv "temp.json" "data_$i.json".
Почему жестко закодированный объект, а не изменение значения из data.json?
Это не очень устойчиво, поскольку вам придется изменить сценарий, если значение объекта изменится.
У меня вопрос: как исправить ошибку?
Вы передаете jq --argjson new_i "$i", что включает переменную new_i в вашем фильтре jq со значением $i.
Однако вы все еще используете bash $i в фильтре, измените его на $new_i.
Тем не менее, рассмотрим следующий фильтр:
for i in {1..10}; do
jq --arg new_i "$i" '.ZZZ[$new_i] = .ZZZ["0"] | del(.ZZZ["0"])' ff;
done
Здесь мы передаем i в jq, а затем
.ZZZ[$new_i] = .ZZZ["0"] «скопировать» объект в новый ключ (поскольку источник всегда будет иметь ключ 0, поскольку вы заранее делаете копию)del(.ZZZ["0"]) удалить ключевой объект 0Объединив это с уже имеющимся циклом for, вы должны создать файлы.
Вам нужно будет использовать
$new_iв фильтре jq, если вы пройдете--argjson new_i "$i"