我的脚本正在从 grep 结果设置数组,这样空的 grep 结果也存储在数组中。
例如。
set -x
echo "${Arr[@]}"
+ echo '' 'word' '' 'word2'
有人可以帮助取消设置这些空值,以便 echo "${#Arr[@]}" 给出 2 而不是 4
尝试过
var=-1 && for i in "${Input_Arr[@]}"; do var=$((var+1)); if [ -z "$i" ]; then unset "${Input_Arr[$var]}"; fi; done
但它不起作用
答案1
首先,不需要发明虚拟索引 - 您可以使用间接运算符访问数组的索引!
其次,"${Input_Arr[$var]}"
是元素的价值;unset
需要元素的姓名,Input_Arr[$var]
或者只是Input_Arr[var]
,因为它已经是一个算术上下文)。所以给出:
$ arr=(foo '' bar '' baz)
$ declare -p arr
declare -a arr=([0]="foo" [1]="" [2]="bar" [3]="" [4]="baz")
然后
$ for i in ${!arr[@]}; do [[ -z ${arr[i]} ]] && unset arr[i]; done
树叶
$ declare -p arr
declare -a arr=([0]="foo" [2]="bar" [4]="baz")
这也适用于关联数组 - 对非数字键进行适当调整(包括双引号扩展以防止潜在的 split + glob):
$ declare -A Arr=(['1st val']=foo ['2nd val']='' ['3rd val']=bar ['4th val']='' ['5th val']=baz)
$ declare -p Arr
declare -A Arr=(["5th val"]="baz" ["2nd val"]="" ["4th val"]="" ["3rd val"]="bar" ["1st val"]="foo" )
$ for i in "${!Arr[@]}"; do [[ -z ${Arr[$i]} ]] && unset Arr["$i"]; done
$ declare -p Arr
declare -A Arr=(["5th val"]="baz" ["3rd val"]="bar" ["1st val"]="foo" )
答案2
如果您希望将剩余的数组元素折叠到从零开始的连续索引,那么创建数组的副本可能是最简单的:
arr1=(foo '' bar '')
arr2=()
for val in "${arr1[@]}"; do
[[ $val ]] && arr2+=( "$val" )
done
这将使 保留arr2
为declare -a arr2=([0]="foo" [1]="bar")
,即 的索引bar
从 2 更改为 1,以避免留下漏洞。
您也可以通过复制各个元素并取消设置最后一个元素来就地完成此操作,但这更多是手动工作。