jq & bash: сделать массив JSON из переменной

я использую jq не для формирования JSON в bash из значений переменных.

получил как сделать простые переменные

$ VAR="one two three"
$ jq -n "{var:"$VAR"}"
{
  "var": "one two three"
}

но пока не могу сделать массивы. У меня

$ echo $ARR
one
two
three

и хотите получить что-то вроде

{
  "arr": ["one", "two", "three"]
}

мне удается получить искаженный вывод, как

$ jq -n "{arr: ["$ARR"]}"
{
  "arr": [
    "onentwonthree"
  ]
}

Как правильно сформировать массив JSON? Может jq когда-нибудь сделать это?

редактировать: вопрос был задан, когда было только jq не 1.3. Теперь, в jq 1.4, можно делать прямо то, что я просил, как @JeffMercado и @peak предложили, upvote для них. Однако не отменит принятие ответа @jbr.

6 ответов


jq делает именно то, что вы скажете ей сделать. jq - это не программа для генерации JSON, а инструмент для его запроса. Что вы делаете с -n switch просто использует его как симпатичный принтер. поэтому, если вы хотите, чтобы он напечатал объект с массивом, содержащим "один", "два", "три", то вы должны сгенерировать его.

VAR="one two three"
VAR=$(echo $VAR | sed -e 's/\(\w*\)/,""/g' | cut -d , -f 2-)
echo "{var: [$VAR]}"

обновление

As Брайан и другие упоминают ниже, что действительно можно создайте JSON с помощью jq, а с версии 1.4 даже можно сделать то, что OP спрашивает напрямую, см., например,Джефф.


в jq 1.3 и выше вы можете использовать :

jq -n --arg v "$VAR" '{"foo": $v}'

И. Е., --arg устанавливает переменную в заданное значение, чтобы вы могли использовать $varname в вашей программе jq, и теперь вам не нужно использовать интерполяцию переменных оболочки в вашу программу jq.

EDIT: из jq 1.5 и выше вы можете использовать --argjson для передачи массива напрямую, например

jq -n --argjson v '[1,2,3]' '{"foo": $v}'

Как только вы загрузили свою переменную, вы должны использовать split фильтр для разделения этой строки на массив.

$ jq -n --arg inarr "${ARR}" '{ arr: $inarr | split("\n") }'

исходная публикация в этой теме упоминает VAR= "один два три". Для такой переменной очень простое решение в jq 1.4 выглядит следующим образом:

$ jq -n -c -M --arg s "$VAR" '{var: ($s|split(" "))}'
{"var":["one","two","three"]}

(это предполагает оболочку Linux или Mac или аналогичную и работает с jq 1.4.)

если символ разделителя является новой строкой, то рассмотрим этот typescript:

$ s=$(printf "a\nb\nc\n")
$ jq -n -c -M --arg var "$s" '{"var": ($var|split("\n"))}'
{"var":["a","b","c"]}

обратите внимание, что строка JSON для символа новой строки -"\n" (не "\n").

третий случай интереса, когда VAR массив Баш. В этом случае может быть приемлемо передать элементы, используя "${VAR [@]}", но в целом следует помнить, что параметр "--arg name value" предназначен только для передачи строк.

в jq>1.4 экспортированные переменные оболочки могут быть переданы с помощью объекта "env", как описано на странице руководства jq.


сначала вы должны использовать -R чтобы прочитать необработанные строки, а затем вы должны slurp все значения с -s:

$ echo -e "one\ntwo\nthree" | jq -R . | jq -s '{"arr": .}'
{
  "arr": [
    "one",
    "two",
    "three"
  ]
}

вы можете использовать следующий синтаксис:

jq --arg keyName "MyVal" '.[]."\($keyName)"[] ./JSONFile.js

для ввода данных, таких как

[{"MyVal":"Value1","MyVal":Value2,"NotMyVal":"Value3"}];

для получения проанализированных данных из JSON с переменными.

этот пример выведет:

"Value1"
"Value2"