shell中的数组
2021-06-13
关键字:
shell中的数组是一个比较特殊的存在。因为在shell中定义变量时总是默认就被定义为数组类型变量。除非我们使用declare命令显式指定变量为其它类型。
换句话说,shell中的数组其实就是多个普通变量的组合而已。事实也确实如此,对数组的大多数操作方式在普通变量中同样有效。
本文简单记述下shell中数组的增、删、改、查的基本操作方式。
1、增
数组的新增即创建数组。shell创建数组的方式严格来讲只有一种:直接创建。
但其实也勉强可以分成以下三种:
1、直接创建;
2、使用元组创建;
3、创建并联数组;
1、直接创建:
与创建普通变量一样,直接使用=赋值即可。如:
array[idx]=value
以下是一个示例程序:
array[0]=p1 array[1]=p2 array[2]=p3
该程序创建了一个名为 array 的数组,该数组拥有 3 个元素内容。
与传统编程语言一样,shell中的数组的起始下标也是0。
不过,与传统编程语言不一样的地方是:shell中的数组允许“跳跃式创建”。一般的编程语言里,甚至在我们的潜意识里,都认为数组的创建及赋值必须是按顺序来的,先把前面的槽位用值填上了才可继续后面的填充。但shell却可以跳跃着来填值。以下是一个shell数组跳跃式创建的示例程序:
#!/bin/bash echo "begin" array[3]=p3 array[10]=p10 array[1]=p1 echo "end"
该程序是完全合法的。这样创建出来的数组其实内部只有 3 个元素,只不过它们的位置确实是在 1 号、3号及10号而已。中间其它下标的值为空。
另外,同样可以使用 declare 命令显式创建数组,语法如下:
#!/bin/bash declare -a array array[0]=p0 array[1]=p1
declare命令的语法可以参考笔者另一篇博文:https://www.cnblogs.com/chorm590/p/14854868.html
2、使用元组创建:
如果说直接赋值是野生武装力量,那元组赋值就必须是正规军部队了。
使用元组创建数组与直接赋值创建相比唯一的区别就是:可以严格按照顺序来填充值。
以下是语法示例:
#!/bin/bash #创建一个具有连续7个元素的数组 array=(1 2 3 4 5 6 7) #创建一个字符串数组 array=("hello" "world" "hello" "rust") #对数组元素而言,双引号不是必须的 array=(hello world hello rust)
3、创建关联数组:
shell中的关联数组其实就是一种映射集合的关系。简单说,它允许我们自定义数组中的索引下标的值,将传统的 0 1 2 3 4 索引下标替换成任意字符串以方便使用 array[key] 的方式查找元素值。以下是关联数组创建的语法示例:
#!/bin/bash declare -A array array=([name]=chorm [edtype]=vim [fruit]=banana)
以上程序使得后续可以在数组的索引中传入对应的字符串型下标来查找对应的元素值,这本质上就是一个key-value对形式的映射集合了,已经有点超越了普通数组的范畴了。
不过,关联数组是一个后来才出现的功能。使用关联数组前必须先以-A参数显式声明数组变量,且运行shell脚本代码的bash的版本不得低于4.0。
其实我们应该隐隐约约能感觉出来,原始的使用数字索引下标的数组定义方式本质上也是“关联数组”形式的,只不过其索引值刚好就是数字而已。关于关联数组到底是不是另一种形式的原始数组的表达,就仁者见仁,智者见智了。笔者是倾向于是的。
2、删
删除数组在本质上就是释放数组及其元素所占用的内存空间,使其变量不再有效而已。
前面有提过,shell中的数组其实就是多个普通变量的组合而已。因此,删除数组及其元素可以使用 unset 命令来实现。另外,除了可以删除整个数组外还可以只删除数组内的某一个元素。
相关语法如下所示:
#!/bin/bash
#删除整个数组
unset array
#删除数组内的某个元素
unset array[n]
#删除关联数组内的某个元素
unset array[key]
3、改
与修改普通变量的值一样,直接将新值赋予数组变量或指定元素即可。
另外,shell中的数组支持替换操作,其语法如下:
${array[*]/要替换的原内容/替换后的内容}
#或
${array[@]/要替换的原内容/替换后的内容}
示例代码如下:
#!/bin/bash array=(1 2 3 4 5) ${array[@]/3/100}
以上代码执行后会将原数组中的 3 替换为 100。
4、查
输出整个数组内容的语法如下所示:
echo "${array[@]}" #或 echo "${array[*]}"
输出指定下标元素:
echo "${array[n]}" echo "${array[key]}"
遍历数组元素:
array=(1 2 3 4 5 6 7 8) for var in ${array[*]} do echo "$var" done