Подтвердить что ты не робот

Цикл через массив массивов строки с пробелами

Я пытаюсь перебрать массив, содержащий другие массивы, и эти массивы состоят из строк с пробелами. Проблема в том, что я не могу сохранить промежуток в строке. Строка с пробелами делится на несколько элементов, если я изменяю IFS на \n, или все элементы массива рассматриваются как 1 элемент, если я оставлю IFS без изменений здесь пример кода:

#!/bin/sh
low1=("AA  QQ" "BB  LL")
low2=("CC" "DD")
low3=("EE" "FF")
high=(low1 low2 low3)

for high_item in ${high[@]}
do
   eval arrayz=\${$high_item[@]}
   #IFS=$'\n'
   for item in $arrayz
   do
      echo $item
   done
done

Вывод:

AA
QQ
BB
LL
CC
DD
EE
FF

Как вы видите, элементы "AA QQ" и "BB LL" были разделены.

Если я раскомментирую строку, которая устанавливает IFS в \n, я получаю следующее:

AA QQ BB LL
CC DD
EE FF

Теперь "AA QQ" и "BB LL" объединены!

В любом случае я могу сохранить эти элементы так же, как они оригинальны... Мне нужен вывод, чтобы выглядеть так:

AA QQ
BB LL
CC 
DD
EE 
FF
4b9b3361

Ответ 1

Я думаю, вы имели в виду, что вывод должен выглядеть так:

AA  QQ
BB  LL
CC
DD
EE
FF

то есть:.

${low1[0]}
${low1[1]}
${low2[0]}
${low2[1]}
${low3[0]}
${low3[1]}

Это может быть выполнено с помощью:

#!/bin/bash

low1=("AA  QQ" "BB  LL")
low2=("CC" "DD")
low3=("EE" "FF")
high=(low1 low2 low3)

for high_item in ${high[@]}
do
    x="${high_item}[@]" # -> "low1[@]"
    arrays=( "${!x}" )

    #IFS=$'\n'
    for item in "${arrays[@]}"
    do
        echo "$item"
    done
done

И пожалуйста всегда используйте #!/bin/bash для bash скриптов.

Объяснение: ${!x} - косвенное изменение переменной. Он вычисляет значение переменной с именем, содержащимся в $x.

Для наших нужд x должен иметь суффикс [@] для расширения массива. Особенно отметим, что это x=${high_item}[@] и не x=${high_item[@]}.

И вы должны оценить его в контексте массива; в противном случае он не будет работать так, как ожидалось (если вы делаете arrays=${!x}).

Ah, и как окончательное замечание: IFS здесь не имеет никакого значения. Пока вы работаете над цитируемыми массивами, IFS не вступает в игру.

Ответ 2

Замените eval косвенным расширением параметра, и вы получите то, что, как я думаю, вы хотите (хотя оно не соответствует вашему текущему выходу:

for high_item in "${high[@]}"
do
    arrayz="$high_item[@]"
    # arrayz is just a string like "low1[@]"
    for item in "${!arrayz}"
    do
        echo $item
    done
done

Обратите внимание на необходимость цитировать расширение массива во внутреннем цикле, чтобы сохранить пробелы в элементах low1.