Bash - Как передать массив в функцию с индексом, определенным в новой функции - PullRequest
1 голос
/ 21 октября 2019

У меня есть текущая функция, используемая для создания массива в стиле меню (в сценарии нельзя использовать ассоциативные массивы).

declare -a array1=("host1" "host2" "host3")
declare -a array2=("ip1" "ip2" "ip3")

function menusetup {

  iter=0
  for ((i=0; i<(count*2); i+=2)); do
    menu[$i]=${array1[$iter]}
    menu[$i+1]=${array2[$iter]}
    ((iter++))
  done
}

menusetup

, что дает мне массив меню с {"host1" "ip1" "host2" "ip2" "host3" "ip3" Thisотлично работает для того, что мне нужно, но теперь я хочу повторно использовать эту функцию, чтобы передать любые 2 массива, что-то вроде этого.

function menusetup {

  iter=0
  for ((i=0; i<(count*2); i+=2)); do
    menu[$i]=${$1[$iter]}
    menu[$i+1]=${$2[$iter]}
    ((iter++))
  done
}

menusetup "${array3[@]}" "${array4[@]}"

Редактировать: я знаю, что во втором примере передается весь список элементовмассив. Я хочу знать, есть ли способ передать и заменить массив

1 Ответ

0 голосов
/ 21 октября 2019

Несмотря на то, что вы можете использовать ссылки на имена bash:

array3=(1 2 3)
array4=(a b c)
menusetup() {
   declare -g menu
   declare -n count1=$1[@]
   count=$(( ${#count1} ))
   iter=0
   for ((i=0; i<count; i+=2)); do
       declare -n el1=$1[$iter]
       declare -n el2=$2[$iter]
       menu[$i]=$el1
       menu[$i+1]=$el2
       ((iter++))
    done
}

menusetup array3 array4
declare -p menu
# will output:
# declare -a menu=([0]="1" [1]="a" [2]="2" [3]="b" [4]="3" [5]="c")

И это правильный и полезный стиль программирования, гораздо лучше и проще думать о bash как о конвейерах. Вам не нужно состояние, вам не нужно «перебирать» массивы.

Думайте о bash как о потоках. То, что вы делаете здесь, это то, что вы "zip" - два массива. Поэтому сначала напечатайте каждый элемент массива на элементах, разделенных символом новой строки, а затем используйте paste для объединения двух потоков, разделенных символом новой строки, укажите разделитель paste для символа новой строки. Затем прочитайте его в массив, либо с readarray < <(...) или IFS=$'\n' menu=( $(...) ).

Предполагая, что в значениях массива нет символов новой строки, всю работу, которую выполняет ваша функция, можно выполнить просто:

readarray -t menu < <(paste -d$'\n' <(printf "%s\n" "${array3[@]}") <(printf "%s\n" "${array4[@]}") )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...