gpt4 book ai didi

bash - 如何在不展平数组的情况下从 bash 数组中删除元素

转载 作者:行者123 更新时间:2023-12-05 00:41:37 26 4
gpt4 key购买 nike

我想做一个像这样的 bash 数组的函数:

a=("element zero" "element one" "element two")

并删除一个元素,如“元素一”,并留下这样的数组:

a=("element zero" "element two")

这样 echo $a[1] 将打印出 element two 而不是 zero

我已经看到了几次尝试,但还没有找到一个干净利落的或没有将具有空格的元素分解为多个元素的尝试。或者只是将元素设置为空白(即不移动后续数组元素的索引)。

最佳答案

# initial state
a=( "first element" "second element" "third element" )

# to remove
unset a[0]

# to reindex, such that a[0] is the old a[1], rather than having the array
# start at a[1] with no a[0] entry at all
a=( "${a[@]}" )

# to print the array with its indexes, to check its state at any stage
declare -p a

...现在,对于一个函数,如果你有 bash 4.3,你可以使用 namevars 来做到这一点,而无需任何 eval:

remove() {
local -n _arr=$1 # underscore-prefixed name to reduce collision likelihood
local idx=$2
unset _arr[$idx] # remove the undesired item
_arr=( "${_arr[@]}" ) # renumber the indexes
}

对于旧版本的 bash,它有点粘:

remove() {
local cmd
unset "$1[$2]"
printf -v cmd '%q=( "${%q[@]}" )' "$1" "$1" && eval "$cmd"
}

printf%q 格式字符串一起使用有点偏执——它使恶意选择的值(在本例中为变量名)更难执行他们选择的操作,而不是简单地失败而没有效果。


说了这么多 -- 如果你不要重新编号你的数组会更好。如果您放弃重新编号步骤,这样在删除条目 a[1] 后,您只需在该索引 处拥有一个没有内容的稀疏数组(这与该索引处的空字符串不同-- bash“数组”实际上存储为链表或哈希表[在关联的情况下],根本不是数组,所以稀疏数组是内存效率的),删除操作要快得多。 p>

如果您检索时向数组询问其键而不是在外部提供它们,这不会破坏您遍历数组的能力,如下所示:

for key in "${!a[@]}"; do
value="${a[$key]}"
echo "Entry $key has value $value"
done

关于bash - 如何在不展平数组的情况下从 bash 数组中删除元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25436988/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com