#json #jq #key-value
#json #jq #ключ-значение
Вопрос:
У меня есть обычный текстовый файл в формате, подобном этому:
foo: bar
color: blue
names: joe, john, mary, bob, sue
Мне нужно вывести содержимое этого файла в формате JSON:
{
"foo": "bar",
"color": "blue",
"names": ["joe", "john", "mary", "bob", "sue"]
}
Я пытался использовать: jq -R -n '[inputs|split(":")|[{(.0):.[1] | add' testfile
(допустим, имя файла — testfile), но я могу получить только этот результат:
{
"foo": "bar",
"color": "blue",
"names": "joe, john, mary, bob, sue"
}
Что мне нужно сделать, чтобы получить желаемый результат? Я пробовал конвейер split(",")
после [1]
, но он превращает каждую пару значений в массив, чего я не хочу.
Ответ №1:
Всегда разделяйте значение. Если результирующий массив содержит несколько элементов, назначьте его; в противном случае назначьте исходную строку.
reduce (inputs / ": ") as [$k, $v] (.;
.[$k] = ($v / ", " | if has(1) then . else $v end)
)
Или сначала проверьте, содержит ли значение разделитель, а затем разделите, если это имеет больше смысла.
($v | if index(", ") then split(", ") else . end)
Обратите внимание, что для этого необходимо вызвать JQ с помощью -R и -n в командной строке.
Ответ №2:
С --raw-input
помощью, вы ищете что-то вроде этого:
[., inputs] # A
| map(split(": ") # B
| {(.[0]): (.[1] | split(", ") | if length > 1 then . else .[0] end )}) # C
| reduce .[] as $x ({}; . $x) # D
Где:
- A: объединяет первую и последнюю строки в один массив, например
["foo: bar", …]
- B: разделить каждую строку, например
[["foo", "bar"], …]
- C: Преобразуйте каждое подмножество в объект, где первый элемент является ключом, а второй элемент — значением. Значение разделяется на
", "
, но если после разделения остается только один элемент, удалите его. - D: объединить каждый объект в один с
{"foo": "bar"} {"color": "blue"}
, =>{"foo": "bar", "color": "blue", …}