melon@machine: ~/$ cat /tmp/test.json
[
"One Entry Here",
"Two Entry Here",
"Three Entry Here",
"Four Entry Here"
]
melon@machine: ~/$ jq -sr '.[]| @sh' /tmp/test.json
'One Entry Here' 'Two Entry Here' 'Three Entry Here' 'Four Entry Here'
melon@machine: ~/$ BANANA=( 'One Entry Here' 'Two Entry Here' 'Three Entry Here' 'Four Entry Here' )
melon@machine: ~/$ echo ${BANANA[1]}
Two Entry Here
Приведенное выше показано ожидаемое поведение, и показывает мне вручную $ Banana
к выходу JQ
команда.
Такое изменение поведения, если переменная переменная вместо этого используется подстановка команды:
melon@machine: ~/$ BANANA=( $(jq -sjr '.[]| @sh' /tmp/test.json) )
melon@machine: ~/$ echo ${BANANA[1]}
melon@machine: ~/$ echo ${BANANA[0]}
'One Entry Here' 'Two Entry Here' 'Three Entry Here' 'Four Entry Here'
, в то время как это правда, что я пытаюсь преобразовать массив JSON в массив Bash для проигрывателя, и есть и другие предложенные методы, мой вопрос Почему здесь поведение отличается при использовании подстановки команды, и есть ли что-то, что я могу сделать, чтобы повесть вручную ведут вести себя, когда я вручную скопирую и вставку jQ
, выхожу на себя в переменную?
GNU Bash, версия 5.0.3 (1) -Release (X86_64-PC-Linux-GNU)
GNU Bash, версия 5.1.4 (1) -Release (X86_64-PC-Linux-GNU)
melon@machine: ~/$ mapfile -t BANANA < <(jq '.[]' /tmp/test.json)
melon@machine: ~/$ echo ${BANANA[0]}
"One Entry Here"
melon@machine: ~/$ echo ${BANANA[1]}
"Two Entry Here"
MapFile
Работает, но мне все еще интересно разница при использовании замены команды.
Даже после добавления флага -j
jq JQ
для подавления конца новой строки результаты одинаковы.
Я бы сделал один из:
IFS=$'\t' read -ra banana < <(jq -sr '.[] | @tsv' test.json)'
, который дает ожидаемый:
$ declare -p banana
declare -a banana=([0]="One Entry Here" [1]="Two Entry Here" [2]="Three Entry Here" [3]="Four Entry Here")'
или использование объявлено
, который вроде как Eval
, но только для переменных заданий:
declare -a "banana=($(jq -sr '.[] | @sh' test.json))"
Это заставляет оболочку выполнять 2-й раунд расширений, чтобы цитаты, излучаемые JQ, будут правильно обработаны оболочкой. Иначе вы получаете:
$ banana=($(jq -sr '.[] | @sh' test.json))
$ declare -p banana
declare -a banana=([0]="'One" [1]="Entry" [2]="Here'" [3]="'Two" [4]="Entry" [5]="Here'" [6]="'Three" [7]="Entry" [8]="Here'" [9]="'Four" [10]="Entry" [11]="Here'")
или
$ banana=("$(jq -sr '.[] | @sh' test.json)")
$ declare -p banana
declare -a banana=([0]="'One Entry Here' 'Two Entry Here' 'Three Entry Here' 'Four Entry Here'")