将其名称作为bash函数参数传递给数组
我正在编写一个函数,将元素添加到传入参数的数组末尾:将其名称作为bash函数参数传递给数组,bash,Bash,我正在编写一个函数,将元素添加到传入参数的数组末尾: #@function add_elem_to_array: add an element to an array #in: #1 name of the array #2 element to add add_elem_to_array() { elem=$1 array=$2 index=${#array[@]} #get the index where to insert eval "$
#@function add_elem_to_array: add an element to an array
#in:
#1 name of the array
#2 element to add
add_elem_to_array()
{
elem=$1
array=$2
index=${#array[@]} #get the index where to insert
eval "$array[$index]=$elem" #!!!! The problem is here
}
您能帮我找出解决方案吗?假设bash 4.3或更高版本,因此具有名称变量(
declare-n
/local-n
):
支持bash 3.x(特别是包括3.2,在本文撰写时广泛使用的最早版本):
也就是说,如果将
array+=(“$value”)
作为一种可用语法,就不需要函数了,是吗?假设bash 4.3或更高版本,因此具有名称变量(declare-n
/local-n
):
支持bash 3.x(特别是包括3.2,在本文撰写时广泛使用的最早版本):
也就是说,如果将
array+=(“$value”)
作为一种可用的语法,那么就不需要函数了,是吗?我不会为此使用函数:
array+=("$elem")
附加一个元素
如果您确实想要使用函数,并且您有Bash 4.3或更新版本,则可以使用nameref:
add_elem_to_array () {
local elem=$1
local -n arr=$2
arr+=("$elem")
}
我不会为此使用函数:
array+=("$elem")
附加一个元素
如果您确实想要使用函数,并且您有Bash 4.3或更新版本,则可以使用nameref:
add_elem_to_array () {
local elem=$1
local -n arr=$2
arr+=("$elem")
}
您的问题实际上是在确定索引的行中
eval index=\${#${array}[@]} #get the index where to insert
您需要使用eval展开包含数组名称的变量,然后展开表达式以获取其长度。转义第一个美元符号会阻止数组长度请求的扩展,直到转义之后
脚本的其余部分似乎按照您的意愿工作。以下是我使用的调试版本,以显示正在发生的情况:
add_elem_to_array()
{
elem=$1
array=$2
eval index=\${#${array}[@]} #get the index where to insert
echo "elem ='$elem'"
echo "array='$array'"
echo "index='$index'"
eval "$array[$index]=$elem" #!!!! The problem is here
}
arr=(This is a test)
echo "arr = '${arr[@]}'"
add_elem_to_array "one" arr
echo "arr = '${arr[@]}'"
add_elem_to_array "two" arr
echo "arr = '${arr[@]}'"
您的问题实际上是在确定索引的行中
eval index=\${#${array}[@]} #get the index where to insert
您需要使用eval展开包含数组名称的变量,然后展开表达式以获取其长度。转义第一个美元符号会阻止数组长度请求的扩展,直到转义之后
脚本的其余部分似乎按照您的意愿工作。以下是我使用的调试版本,以显示正在发生的情况:
add_elem_to_array()
{
elem=$1
array=$2
eval index=\${#${array}[@]} #get the index where to insert
echo "elem ='$elem'"
echo "array='$array'"
echo "index='$index'"
eval "$array[$index]=$elem" #!!!! The problem is here
}
arr=(This is a test)
echo "arr = '${arr[@]}'"
add_elem_to_array "one" arr
echo "arr = '${arr[@]}'"
add_elem_to_array "two" arr
echo "arr = '${arr[@]}'"
对于Bash 4.3+来说,这是完美的,但是如果您使用的是较旧版本的Bash,就没有简单的解决方案(除非您出于某种可怕的原因想玩弄eval
)。然而,这确实是可以做到的
以下是我突然想到的:
您可以看到数组的大小等于数组的下一个可用索引,但情况并非总是如此。继续:
$ arr[7648]="E"
$ arr+=(F)
$ echo ${#arr[@]}
6
$ declare -p arr
declare -a arr='([0]="A" [1]="B" [2]="C" [3]="D" [7648]="E" [7649]="F")'
第1行:这就是为什么在函数的第一行中,我从
a
(${!arr[@])的索引创建了一个整数数组keys
扩展到arr
的索引。keys
中的最后一个元素应该比我们要放置新元素的索引小1。但是,如果arr
未设置或为空,${!arr[@]}
将扩展为零,因此我将-1
放在键的前面来处理这个问题
第2行:
接下来,我们清除IFS
(使用local
,以避免在函数之外更改它)确保附加元素中的任何尾随或前导空格字符都被保留。如果不清除IFS
,read
和here字符串操作符对于Bash 4.3+来说非常有效,但如果使用的是旧版本的Bash,则没有简单的解决方案(除非你出于某种可怕的原因想玩弄eval
),但是,这确实是可以做到的
以下是我突然想到的:
您可以看到数组的大小等于数组的下一个可用索引,但情况并非总是如此。继续:
$ arr[7648]="E"
$ arr+=(F)
$ echo ${#arr[@]}
6
$ declare -p arr
declare -a arr='([0]="A" [1]="B" [2]="C" [3]="D" [7648]="E" [7649]="F")'
第1行:
这就是为什么在函数的第一行中,我从a
(${!arr[@])的索引创建了一个整数数组keys
扩展到arr
的索引。keys
中的最后一个元素应该比我们要放置新元素的索引小1。但是,如果arr
未设置或为空,${!arr[@]}
将扩展为零,因此我将-1
放在键的前面来处理这个问题
第2行:
接下来,我们清除IFS
(使用local
,以避免在函数之外更改它)为了确保附加元素中的任何尾随或前导空格字符都被保留。在不清除IFS
、read
和here字符串操作符的情况下,这里有一个页面介绍如何在bash@gabrielb David thx中取消对数组元素的引用,但在我的示例中,数组的名称是在param中传递的;与在哪个版本的情况不同bash?你有namevars吗?顺便说一句,使用${{数组[@]}
获取下一个要写入的索引是错误的。在bash中数组可以稀疏-这意味着你可以有一个数组声明-a arr=([15]=1)
,只有一个项,该项的索引是15
,而不是0
${code>{
不会给你下一个索引,在这种情况下插入是安全的。@Gabrielb David,请避免链接TLDP作为参考——他们的文档维护不足,并且(特别是在ABS的情况下)倾向于展示不良做法。是一个更积极维护的参考,详细介绍了数组的使用,而全面讨论了关联数组以及间接赋值和间接查找(更接近OP在此实际查找的内容).bash@GabrieleB David thx中有一个关于取消引用数组元素的页面,但在我的例子中,数组的名称是在param中传递的;与bash的哪个版本不同?您有namevars吗?顺便说一句,使用${#array[@]}
获取下一个要写入的索引是错误的。在bash中数组可以是稀疏的-这意味着您可以有一个数组declare-a arr=([15]=1)
,只有一个项,并且