我想删除数组中的最后一个条目,我希望数组向我显示当我使用${#array[@]}
时它的条目少了1个。这是我正在使用的当前行:
unset GreppedURLs[${#GreppedURLs[@]} -1]
请纠正我并告诉我正确的方法。
答案 0 :(得分:46)
你的答案是(差不多)正确for non-sparse indexed arrays¹:
unset 'arr[${#arr[@]}-1]'
(注意单引号:它们阻止路径名扩展)。
演示:
arr=( a b c )
echo ${#arr[@]}
3
for a in "${arr[@]}"; do echo "$a"; done
a b c
unset 'arr[${#arr[@]}-1]'
for a in "${arr[@]}"; do echo "$a"; done
a b
<强>警句强>
echo ${#arr[@]}
2
(GNU bash,版本4.2.8(1)-release(x86_64-pc-linux-gnu))
¹@Wil提供了适用于各种数组的excellent answer
答案 1 :(得分:16)
您必须在-1
之前删除空白。
答案 2 :(得分:7)
如果您想要一个不会吃掉小猫的答案,请试试这个:
array=([1]=1 {2..5} [10]=6);
# declare -a array='([1]="1" [2]="2" [3]="3" [4]="4" [5]="5" [10]="6}")'
index=("${!array[@]}");
# declare -a index='([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="10")'
unset 'array[${index[@]: -1}]';
# declare -a array='([1]="1" [2]="2" [3]="3" [4]="4" [5]="5")'
你有它 - 删除最后一个元素。现在,我将提供一个更容易回答,可能满足您的需求,但有一点需要注意:
array=([1]=1 {2..5} [10]=6);
# declare -a array='([1]="1" [2]="2" [3]="3" [4]="4" [5]="5" [10]="6}")'
array=("${array[@]::${#array[@]}-1}");
# declare -a array='([0]="1" [1]="2" [2]="3" [3]="4" [4]="5")'
此版本采用快捷方式。它重新索引数组并删除最后一个元素。不幸的是,您还可以看到索引尚未维护。价值观及其顺序一直如此。如果你不关心索引,那么这可能是你想要的答案。
上述两个答案也适用于bash 4 Associative Arrays。
-
选择的答案并不安全。这是一个例子:
array=([1]=1 {2..5} [10]=6);
# declare -a array='([1]="1" [2]="2" [3]="3" [4]="4" [5]="5" [10]="6")'
unset 'arr[${#arr[@]}-1]';
# declare -a array='([1]="1" [2]="2" [3]="3" [4]="4" [10]="6")'
好的,因为你可以看到它取消了索引为5的元素,因为它错误地计算了数组最后一个元素的索引。它失败了,因为它假设所有数组都是从零开始的,而不是稀疏的。这个答案将在数组开始时失败,这些数组从零以外的任何数据开始,稀疏的数组,并且显然必须失败的关联数组与&#39; fubar&#39;为最后一个元素。
答案 3 :(得分:5)
对于任何索引数组(稀疏或非稀疏),因为bash 4.3+(和ksh93 +),这是最简单的解决方案:
unset 'array[-1]'
如果-1是算术表达式或变量,则需要引号来避免bash中的shell扩展。这也可以正常工作:
a=3; unset 'arr[ a - 4 * 1 ]'
但如果不加引号(''
),*将无效,因为*将扩展到当前工作目录($pwd
)中的文件列表。
对于较旧的bash版本:从非bash 3.0开始,对于非稀疏数组:
unset 'arr[ ${#arr[@]}-1 ]'
示例:
$ arr=( {a..i} ); declare -p arr
declare -a arr=([0]="a" [1]="b" [2]="c" [3]="d" [4]="e" [5]="f" [6]="g" [7]="h")
$ unset 'arr[ ${#arr[@]}-1 ]'; declare -p arr
declare -a arr=([0]="a" [1]="b" [2]="c" [3]="d" [4]="e" [5]="f" [6]="g")
这将不适用于稀疏数组(有一些漏洞):
$ arr=( {a..g} [9]=i ); declare -p arr
declare -a arr=([0]="a" [1]="b" [2]="c" [3]="d" [4]="e" [5]="f" [6]="g" [9]="i")
$ unset 'arr[ ${#arr[@]}-1 ]'; declare -p arr
declare -a arr=([0]="a" [1]="b" [2]="c" [3]="d" [4]="e" [5]="f" [6]="g" [9]="i")
这是因为元素数量(${#arr[@]}
)为8
而8-1
为7
。
因此,该命令将取消设置arr[7]
,这不存在。什么都没做。
一个解决方案,也适用于关联数组(无论它可能意味着“未排序列表中的最后一个元素”)是生成一个新的索引数组。
然后使用最后一个索引取消设置该元素。
假设arr
已经定义(对于bash 3.0 +):
$ index=( "${!arr[@]}" ) # makes index non-sparse.
$ unset 'arr[${index[@]}-1]' # unset the last index.
$ declare -p arr
declare -a arr=([0]="a" [1]="b" [2]="c" [3]="d" [4]="e" [5]="f" [6]="g")
稍微便于携带(在ksh93中工作),看起来很难看,解决方法是:
$ arr=( {a..e} [9]=i )
$ index=( "${!arr[@]}" )
$ unset "arr[ ${index[${#index[@]}-1]} ]" # Yes, double quotes.
$ declare -p arr
declare -a arr=([0]="a" [1]="b" [2]="c" [3]="d" [4]="e")
或(同样,ksh的双引号):
$ unset "arr[${index[@]: -1}]"
如果您想避开空格和负数,请将其变为变量:
$ a="-1"; unset "arr[${index[@]:a}]"
答案 4 :(得分:0)
以下内容适用于Mac/bash@3.x和Linux(ubuntu/bash@4.x)
unset arr[$[${#arr[@]}-1]] # non-sparse array only
更多详细信息:
len=${#arr[@]}
idx=$[$len-1] # <=> $(($len-1))
unset arr[$idx]
答案 5 :(得分:0)
在您的函数中,您可以添加以下内容:
target="${@:$(($#)):1}"
set -- "${@:1:$(($#-1))}"