Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将其名称作为bash函数参数传递给数组_Bash - Fatal编程技术网

将其名称作为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)
,只有一个项,并且