У меня есть данные JSON формы ниже. Я хочу преобразовать его, превратив ключ каждой записи в поле этой записи в потоковом режиме. Моя проблема: я не знаю, как это сделать, не обрезая ключ и не теряя его. Я вывел необходимую структуру потока, см. Внизу.
Вопрос: как преобразовать входные данные в поток без потери ключа?
Данные:
{
"foo" : {
"a" : 1,
"b" : 2
},
"bar" : {
"a" : 1,
"b" : 2
}
}
Не потоковое преобразование использует:
jq 'with_entries(.value += {key}) | .[]'
получают:
{
"a": 1,
"b": 2,
"key": "foo"
}
{
"a": 1,
"b": 2,
"key": "bar"
}
Теперь, если мой файл данных очень очень большой, я бы предпочел потоковую передачу:
jq -ncr --stream 'fromstream(1|truncate_stream(inputs))`
Проблема: при этом усекаются ключи "foo"
и "bar"
. С другой стороны, не обрезать поток и просто вызывать fromstream(inputs)
довольно бессмысленно: это делает целую часть --stream
бездействующей, а jq
считывает все в память.
Структура потока следующая с использованием . | tostream
:
[
[
"foo",
"a"
],
1
]
[
[
"foo",
"b"
],
2
]
[
[
"foo",
"b"
]
]
[
[
"bar",
"a"
],
1
]
[
[
"bar",
"b"
],
2
]
[
[
"bar",
"b"
]
]
[
[
"bar"
]
]
в то время как с усечением, . as $dot | (1|truncate_stream($dot | tostream))
, структура:
[
[
"a"
],
1
]
[
[
"b"
],
2
]
[
[
"b"
]
]
[
[
"a"
],
1
]
[
[
"b"
],
2
]
[
[
"b"
]
]
Похоже, что для того, чтобы построить поток так, как мне нужно, мне нужно будет сгенерировать следующую структуру (я вставил [["foo"]]
после завершения первой записи):
[
[
"foo",
"a"
],
1
]
[
[
"foo",
"b"
],
2
]
[
[
"foo",
"b"
]
]
[
[
"foo"
]
]
[
[
"bar",
"a"
],
1
]
[
[
"bar",
"b"
],
2
]
[
[
"bar",
"b"
]
]
[
[
"bar"
]
]
Превращая это в строку jq
может потреблять, я действительно получаю то, что мне нужно (см. Также фрагмент здесь: https://jqplay.org/s/iEkMfm_u92):
fromstream([ [ "foo", "a" ], 1 ],[ [ "foo", "b" ], 2 ],[ [ "foo", "b" ] ],[["foo"]],[ [ "bar", "a" ], 1 ],[ [ "bar", "b" ], 2 ],[ [ "bar", "b" ] ],[ [ "bar" ] ])
получают:
{
"foo": {
"a": 1,
"b": 2
}
}
{
"bar": {
"a": 1,
"b": 2
}
}
Окончательный результат (см. https://jqplay.org/s/-UgbEC4BN8) будет:
fromstream([ [ "foo", "a" ], 1 ],[ [ "foo", "b" ], 2 ],[ [ "foo", "b" ] ],[["foo"]],[ [ "bar", "a" ], 1 ],[ [ "bar", "b" ], 2 ],[ [ "bar", "b" ] ],[ [ "bar" ] ]) | with_entries(.value += {key}) | .[]
1049 * получая *
{
"a": 1,
"b": 2,
"key": "foo"
}
{
"a": 1,
"b": 2,
"key": "bar"
}