Я пытаюсь использовать jq для преобразования некоторых флагов командной строки в JSON эквивалент.
Флаги выглядят следующим образом, где идея состоит в том, чтобы преобразовать (необязательный) флаг f в JSON поле "foo" и (необязательно) флаг b в поле JSON "bar":
{
"flags": [
"f1",
"b2",
"f3b4",
"b6f5"
]
}
Получить поля foo очень просто:
.flags[] | match("f([0-9][0-9]*)") | .captures[0].string | tonumber | { "foo": . }
То же самое для полей бара (скажите, если есть лучшие способы сделать это с помощью jq):
.flags[] | match("b([0-9][0-9]*)") | .captures[0].string | tonumber | { "bar": . }
Как объединить выходные данные этих двух фильтров так, чтобы каждая строка входных флагов отображалась в один JSON объект без / одного / обоих необязательных полей?
Двумя соответствующими механизмами являются оператор запятой jq (для разделения одного потока между несколькими фильтрами) и оператор + jq (для объединения объектов в один объект). Применение оператора запятой является простым:
.flags[] | (match("f([0-9][0-9]*)") | .captures[0].string | tonumber | { "foo": . }), (match("b([0-9][0-9]*)") | .captures[0].string | tonumber | { "bar": . })
Однако, это дает отдельный объект для каждого совпадения:
{
"foo": 1
}
{
"bar": 2
}
{
"foo": 3
}
{
"bar": 4
}
{
"foo": 5
}
{
"bar": 6
}
Так что конкретная проблема c здесь состоит в том, как соединить эти два объекты вместе, используя оператор +. Последний вывод, который я пытаюсь получить, - это когда поля foo и bar находятся в одном и том же объекте:
{
"foo": 1
}
{
"bar": 2
}
{
"foo": 3,
"bar": 4
}
{
"foo": 5,
"bar": 6
}
Как лучше всего добиться этого с помощью jq?