2015-01-29 4 views
2

Я пытаюсь изменить массив, который я передал в качестве параметра функции. До сих пор у меня есть пустой массив вне функции:Изменить параметр функции массива Bash

buckets=() 

Тогда у меня есть функция, которая принимает 2 аргумента. Первый аргумент - пустой массив, который я хочу заполнить. Второй аргумент - это имя файла, который содержит данные, которые я хочу использовать для заполнения массива.

До сих пор я создал временный массив. Затем заполните временный массив содержимым файла. Это, как я могу это сделать:

fillarray() 
{ 
# Declare the paramater as a temporary array 
declare -a tempArray=("${!1}") 

# Fill it up 
while IFS= read -r entry; do 
    tempArray+=("$entry") 
done < <(jq -r '.data | .[].name' $2) 

Заключительный шаг, чтобы установить массив параметров (ака ковши), чтобы быть содержимое временного массива, который мы только что завалил. Любые предложения о том, как это сделать?

+0

если ваш tempArray имеет то, что вам нужно, а затем скопировать его в массив ведер будет легко, как: Unix = ('Debian' 'Red hat' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux'); Linux = ("$ {Unix [@]}"); echo $ {Linux [@]}; См. Это для дополнительных операций: http://www.thegeekstuff.com/2010/06/bash-array-tutorial/ --- ИЛИ см. Это, чтобы скопировать массив в другой http://stackoverflow.com/questions/19417015/bash -copy-from-one-array-to-another –

+0

@ArunSangal Пример, который вы даете работам, если у меня есть и знаю имена переменных. Моя проблема связана с общими параметрами внутри функции, которые изменяют переменную вне функции. Я пытаюсь реорганизовать свой код, поэтому мне не нужно повторять сам. Вот почему я пытаюсь захватить этот fillarray как функцию и передать массив, который я хочу заполнить. Спасибо за учебники. Я прочту их, чтобы они стали более знакомы с bash. – honestemu3

ответ

5

В BASH 4.3+ вы можете просто передать массив по названию ссылки. Таким образом, ваша функция может быть упрощена:

fillarray() { 
    # tempArray is a reference to array name in $1 
    local -n tempArray="$1" 
    while IFS= read -r entry; do 
     tempArray+=("$entry") 
    done < <(jq -r '.data | .[].name' "$2") 
} 

Тогда называют его:

buckets=() 
fillarray buckets file.json 

И проверить это, как:

declare -p buckets 

EDIT: Чтобы заставить его работать на BASH 3.2 использование ниже фрагмента:

fillarray() { 
    # $2 is current length of the array 
    i=$2 
    while IFS= read -r entry; do 
     read ${1}"[$i]" <<< "$entry" 
     ((i++)) 
    done < <(jq -r '.data | .[].name' "$3") 
} 

Тогда называют его:

buckets=() 
fillarray buckets ${#buckets[@]} file.json 
+0

К сожалению, у меня есть bash 3.2.53. Поэтому local -n возвращает ошибку использования. – honestemu3

+0

ok Я добавил раздел для BASH 3.2, а также – anubhava

+0

Это сработало. Как вы можете пояснить, вы можете объяснить, что означает '<<<' и двойная скобка вокруг 'i ++'? А также почему нам не нужно ставить '' 'перед' i', когда мы его увеличиваем? – honestemu3

0

Другим путем через eval,

fillarray() { 
local tempArray; 

while IFS= read -r entry; do 
    tempArray[${#tempArray[@]}]="$entry"; 
done < <(jq -r '.data | .[].name' $2); 

eval $1=\('"${tempArray[@]}"'\); 
} 
+0

Когда я немного поработал, я нашел это возможным решением. Многие утверждают, что это работает, но я действительно не понимаю, как это сделать.Что такое eval, что делает его таким ... особенным? Я также читал, что это может привести к некоторым проблемам безопасности? Я не уверен, как это сделать, но если я смогу понять, что делает eval, то я мог видеть, как проблема безопасности может быть проблемой. Баш странный. – honestemu3

+1

Если 1 доллар содержит, например, «ведра»; код eval эквивалентен 'buckets = ($ {tempArray [@]})', то есть tempArray копируется в массив buckets. – xae

Смежные вопросы