#json #max #jq
#json #макс #jq
Вопрос:
У меня есть набор резервных копий, который описывается json. Пример приведен ниже. Я хочу подсчитать, сколько резервных копий было добавлено с момента последнего полного резервного копирования. Я пытаюсь выбрать максимальную временную метку записи с типом «full», поэтому после этого я посчитаю, сколько записей с типом «incr» имеет большую временную метку.
{
"archive": [
{
"database": {
"id": 1
},
"id": "11-1",
"max": "0000000A000018B90000006A",
"min": "0000000A0000167D000000C7"
}
],
"backup": [
{
"archive": {
"start": "0000000A0000181600000030",
"stop": "0000000A0000181C00000083"
},
"backrest": {
"format": 5,
"version": "2.28"
},
"database": {
"id": 1
},
"info": {
"delta": 417875448942,
"repository": {
"delta": 67466720725,
"size": 67466720725
},
"size": 417875448942
},
"label": "20201213-200009F",
"prior": null,
"reference": null,
"timestamp": {
"start": 1607878809,
"stop": 1607896232
},
"type": "full"
},
{
"archive": {
"start": "0000000A0000182900000065",
"stop": "0000000A0000182F00000069"
},
"backrest": {
"format": 5,
"version": "2.28"
},
"database": {
"id": 1
},
"info": {
"delta": 122520170241,
"repository": {
"delta": 19316550760,
"size": 67786280115
},
"size": 416998156028
},
"label": "20201213-200009F_20201214-200009I",
"prior": "20201213-200009F",
"reference": [
"20201213-200009F"
],
"timestamp": {
"start": 1607965209,
"stop": 1607974161
},
"type": "incr"
},
{
"archive": {
"start": "0000000A0000185B000000DD",
"stop": "0000000A0000185B000000F4"
},
"backrest": {
"format": 5,
"version": "2.28"
},
"database": {
"id": 1
},
"info": {
"delta": 126982395984,
"repository": {
"delta": 19541379733,
"size": 67993072945
},
"size": 421395153101
},
"label": "20201213-200009F_20201217-200105I",
"prior": "20201213-200009F_20201214-200009I",
"reference": [
"20201213-200009F",
"20201213-200009F_20201214-200009I"
],
"timestamp": {
"start": 1608224465,
"stop": 1608233408
},
"type": "incr"
}
]
}
Я попытался завершить первую часть этой командой, но в ней говорится, что «число (1607896232) и число (1607896232) не могут быть повторены»
.[0] |.backup[] | select(.type=="full").timestamp.stop|max
Я пробовал sort_by, но безуспешно. Итак, что я здесь делаю не так?
Ответ №1:
С помощью общей вспомогательной функции для подсчета, вот полное решение, предполагая, что вы хотите считать на основе .timestamp.start
:
def count(s): reduce s as $x (0; . 1);
.backup
| (map( select( .type == "full" ).timestamp.stop) | max) as $max
| count(.[] | select( .type == "incr" and .timestamp.start > $max))
Используя max/1
Для больших массивов, вероятно, было бы более эффективно использовать потоковую версию max
:
def count(s): reduce s as $x (0; . 1);
# Note: max(empty) #=> null
def max(s):
reduce s as $s (null; if $s > .m then $s else . end);
.backup
| max(.[] | select( .type == "full" ).timestamp.stop) as $max
| count(.[] | select( .type == "incr" and .timestamp.start > $max))
Ответ №2:
max
ожидает массив.
[ .backup[] | select( .type == "full" ).timestamp.stop ] | max
или
.backup | map( select( .type == "full" ).timestamp.stop ) | max
Ответ №3:
Итак, после того, как я решил проблему с получением конкретного значения (спасибо @ikegami), я решил весь свой вопрос таким образом
jq '(.[0] |[.backup[] | select(.type=="full").timestamp.stop]|max) as $i| [.[0] |.backup[] | select(.type=="incr" and .timestamp.stop>$i)]|length
Не уверен, что это оптимально, но все равно работает.
Ответ №4:
Вот также альтернативное (не jq) решение, как добиться того же запроса JSON с jtc
помощью tool:
bash $ <input.json jtc -jw'[timestamp]:<>G:[-1][type]' / -w'<full><>k'
2
PS. Я разработчик jtc
PPS процессора unix JSON
. вышеуказанный отказ от ответственности требуется SO.