在索引数组中说到数组中有元素删除时,使用for((expr1;expr2;expr3 ))访问,如何过滤掉unset状态的元素。
$ array_name=([0]="a" [1]="bb" [2]="ccc" [3]="dddd")
$ unset array_name[2]
$ for((i=0;i<=4-1;i++)); do echo ${array_name[i]}; done
a
bb
dddd
$
给出2种方法:
第1种,若能获取到数组array_name的索引,那缺失索引代表的元素就是unset状态。在字符串处理中提到了变量扩展,其提供了获取数组索引列表的功能(不包含被删除元素的索引),基本形式是${!name[@]}或${!name[@*}。
$ echo ${!array_name[@]}
0 1 3
$ for i in $(echo ${!array_name[@]}); do echo ${array_name[$i]}; done
a
bb
dddd
$
该方法类似于索引数组中说到的第一种for循环,相比稍微有些啰嗦。
$ for i in "${array_name[@]}"; do echo $i; done
a
bb
dddd
$
第2种,第二种for循环for((i=0;i<=4-1;i++)),访问到了unset状态的元素,能否直接判断出其为unset状态呢?
在字符串处理中提到的变量扩展中说到了变量赋值的4种形式,其会根据变量的unset或空值状态,进行下一步处理。与其对应的还有4种形式,其会根据变量的unset状态,进行下一步处理。对应关系,及其含义如下。
${parameter:-word} -> ${parameter-word}:若变量parameter未设置,就返回word(变量parameter状态不变);否则返回变量parameter的值(用于测试变量unset状态)。
${parameter:=word} -> ${parameter=word}:若变量parameter未设置,就将word赋值给变量parameter,然后返回变量parameter的值(变量parameter状态发生改变)。否则返回变量parameter的值。
${parameter:?word} -> ${parameter?word}:若变量parameter未设置,就输出word至STDERR(变量parameter状态不变);否则返回变量parameter的值。
${parameter:+word} -> ${parameter+word}:若变量parameter是非空值或空值,就返回word(变量parameter原值不变);否则返回变量parameter原状态值。
根据第一条规则可判断出unset状态的元素(不使用第二条,是其改变了数组状态)。
$ for((i=0;i<=4-1;i++)); do flag=${array_name[i]-word}; test "$flag" == "word" || echo ${array_name[i]}; done
a
bb
dddd
这里再想下如何判断变量是空值状态呢?对于unset,或空值状态的变量,长度都是0。
$ unset parameter
$ echo ${#parameter}
0
$ parameter=""
$ echo ${#parameter}
0
根据第四条规则,若变量parameter是非空值或空值,且长度为0,则其为空值状态。
说到Bash中数组这种数据类型,和Python中的list差不多,对于list常见操作有append,pop和insert,Bash数组也能模拟出这些动作(其中第二,三组,也是变量扩展提供的功能)。
In [26]: array_name=["a", "bb", "ccc", "dddd"]
In [27]: array_name.append("zz")
对应:
$ array_name=([0]="a" [1]="bb" [2]="ccc" [3]="dddd")
$ array_name=(${array_name[@]} "zz")
In [31]: array_name.pop()
Out[31]: 'zz'
对应:
$ array_name=(${array_name[@]:0:$((${#array_name[@]}-1))})
In [33]: array_name.pop(0)
Out[33]: 'a'
对应:
$ array_name=(${array_name[@]:1})
In [44]: array_name.insert(0,"yy")
对应:
$ array_name=("yy" ${array_name[@]})
另外在索引数组也提到了,Bash也支持关联数组(无顺序性),使用时需进行显式定义。
$ declare -A array
$ array=([width]=2 [height]=4 [depth]=6)
$ for i in ${!array[@]}; do echo ${array[$i]}; done
6
4
2
若感兴趣可关注订阅号”数据库最佳实践”(DBBestPractice).
转载于:https://blog.51cto.com/coveringindex/2322495