Bash - 如何将数组传递给函数,并在新函数中定义索引
Bash - How to pass array to function, with index defined in new function
我有这个当前函数用于创建菜单样式的数组(场景中不能使用关联数组)。
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"
的菜单数组
这非常适合我的需要,但现在我想重用这个函数来传递任何 2 个数组,就像这样。
function menusetup {
iter=0
for ((i=0; i<(count*2); i+=2)); do
menu[$i]=${[$iter]}
menu[$i+1]=${[$iter]}
((iter++))
done
}
menusetup "${array3[@]}" "${array4[@]}"
编辑:我知道第二个示例传递了数组的整个元素列表。我想知道是否有办法传递和替换数组
虽然您可以使用 bash namereferences:
array3=(1 2 3)
array4=(a b c)
menusetup() {
declare -g menu
declare -n count1=[@]
count=$(( ${#count1} ))
iter=0
for ((i=0; i<count; i+=2)); do
declare -n el1=[$iter]
declare -n el2=[$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 视为管道会更好、更容易。你不需要状态,你不需要 "iterate" 遍历数组。
将 bash 视为流。您在这里所做的是 "zip"-ing 两个数组。所以首先在换行符分隔的项目上打印每个数组元素,然后使用 paste
将两个换行符分隔的流连接在一起,将 paste
分隔符指定为换行符。然后使用 readarray < <(...)
或 IFS=$'\n' menu=( $(...) )
将其读入数组。
假设数组值中没有换行符,您的函数所做的全部工作可以简单地完成:
readarray -t menu < <(paste -d$'\n' <(printf "%s\n" "${array3[@]}") <(printf "%s\n" "${array4[@]}") )
我有这个当前函数用于创建菜单样式的数组(场景中不能使用关联数组)。
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"
的菜单数组
这非常适合我的需要,但现在我想重用这个函数来传递任何 2 个数组,就像这样。
function menusetup {
iter=0
for ((i=0; i<(count*2); i+=2)); do
menu[$i]=${[$iter]}
menu[$i+1]=${[$iter]}
((iter++))
done
}
menusetup "${array3[@]}" "${array4[@]}"
编辑:我知道第二个示例传递了数组的整个元素列表。我想知道是否有办法传递和替换数组
虽然您可以使用 bash namereferences:
array3=(1 2 3)
array4=(a b c)
menusetup() {
declare -g menu
declare -n count1=[@]
count=$(( ${#count1} ))
iter=0
for ((i=0; i<count; i+=2)); do
declare -n el1=[$iter]
declare -n el2=[$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 视为管道会更好、更容易。你不需要状态,你不需要 "iterate" 遍历数组。
将 bash 视为流。您在这里所做的是 "zip"-ing 两个数组。所以首先在换行符分隔的项目上打印每个数组元素,然后使用 paste
将两个换行符分隔的流连接在一起,将 paste
分隔符指定为换行符。然后使用 readarray < <(...)
或 IFS=$'\n' menu=( $(...) )
将其读入数组。
假设数组值中没有换行符,您的函数所做的全部工作可以简单地完成:
readarray -t menu < <(paste -d$'\n' <(printf "%s\n" "${array3[@]}") <(printf "%s\n" "${array4[@]}") )