Поведение массива Bash отличается при использовании подстановки команды

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 для подавления конца новой строки результаты одинаковы.

0
задан 9 March 2021 в 20:53

1 ответ

Я бы сделал один из:

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'")
2
ответ дан 18 March 2021 в 23:27

Другие вопросы по тегам:

Похожие вопросы: