преобразование строк в json в bash
Я хотел бы преобразовать список в массив JSON. Я смотрю на jq
для этого, но примеры в основном касаются разбора JSON (не создавая его). Было бы неплохо знать, что произойдет правильный побег. Мой список - это однострочные элементы, поэтому новая строка, вероятно, будет лучшим разделителем.
5 ответов
Я также пытался преобразовать кучу строк в массив JSON и был в тупике, пока не понял, что -s
был единственным способом, которым я мог обрабатывать более одной строки за раз в jq
выражение, даже если это означало, что мне придется парсить строку вручную.
jq -R -s -c 'split("\n")' < just_lines.txt
-
-R
для чтения raw input -
-s
читать все входные данные как одну строку -
-c
чтобы не очень печатать вывод
легко peasy.
Edit: я на jq
≥ 1.4, что, по-видимому, когда split
встроенный был введен.
вы также можете использовать jq -R .
форматировать каждую строку как строку JSON, а затем jq -s
(--slurp
) чтобы создать массив для входных строк после их разбора как JSON:
$ printf %s\n aa bb|jq -R .|jq -s .
[
"aa",
"bb"
]
метод в ответе chbrown добавляет пустой элемент в конец, если вход заканчивается лентой, но вы можете использовать printf %s "$(cat)"
чтобы удалить конечные linefeeds:
$ printf %s\n aa bb|jq -R -s 'split("\n")'
[
"aa",
"bb",
""
]
$ printf %s\n aa bb|printf %s "$(cat)"|jq -R -s 'split("\n")'
[
"aa",
"bb"
]
если входные строки не содержат символов управления ASCII (которые должны быть экранированы в строках в допустимом JSON), вы можете использовать sed
:
$ printf %s\n aa bb|sed 's/["\]/\&/g;s/.*/"&"/;1s/^/[/;$s/$/]/;$!s/$/,/'
["aa",
"bb"]
--raw-input, затем --slurp
просто резюмируя то, что другие сказали в надежде быстрее понять форму:
cat /etc/hosts | jq --raw-input . | jq --slurp .
вернет вас:
[
"fe00::0 ip6-localnet",
"ff00::0 ip6-mcastprefix",
"ff02::1 ip6-allnodes",
"ff02::2 ip6-allrouters"
]
объяснение
--raw-input/-R:
Don´t parse the input as JSON. Instead, each line of text is passed
to the filter as a string. If combined with --slurp, then the
entire input is passed to the filter as a single long string.
--slurp/-s:
Instead of running the filter for each JSON object in the input,
read the entire input stream into a large array and run the filter
just once.
Я нашел в man-странице для jq и через эксперименты то, что мне кажется более простым ответом.
$ cat test_file.txt | jq -Rsc '. / "\n" - [""]'
["aa","bb"]
- R читать, не пытаясь разобрать json,- s говорит, чтобы прочитать все входные данные как одну строку, а-c для однострочного вывода-не обязательно, но это то, что я искал.
затем в строке я передаю jq,'. говорит Возьми ввод, как это. '/\N ' говорит разделить строку (разделить ее) на новые строки. '- [""] 'Говорит, чтобы удалить из результирующего массива любые пустые строки (в результате дополнительной новой строки в конце).
Это одна строка и без каких-либо сложных конструкций, используя только простые встроенные функции jq.
обновление: если ваш jq имеет inputs
вы можете просто написать:
jq -R [inputs] /etc/hosts
для создания массива строк JSON.