27. 数组
新版本的Bash支持一维数组。 数组元素可以使用符号variable[xx] 来初始化。另外,脚本可以使用declare -a variable语句来指定一个数组。 如果想引用一个数组元素(也就是取值),可以使用大括号,访问形式为 ${element[xx]} 。
例子 27-1. 简单的数组使用
#!/bin/bash
area[11]=23
area[13]=37
area[51]=UFOs
# 数组成员不一定非得是相邻或连续的。
# 数组的部分成员可以不被初始化。
# 数组中允许空缺元素。
# 实际上,保存着稀疏数据的数组(“稀疏数组”)
#+ 在电子表格处理软件中是非常有用的。
echo -n "area[11] = "
echo ${area[11]} # 需要{大括号}。
echo -n "area[13] = "
echo ${area[13]}
echo "Contents of area[51] are ${area[51]}."
# 没被初始化的数组成员打印为空值(null变量)。
echo -n "area[43] = "
echo ${area[43]}
echo "(area[43] unassigned)"
echo
# 两个数组元素的和被赋值给另一个数组元素。
area[5]=`expr ${area[11]} + ${area[13]}`
echo "area[5] = area[11] + area[13]"
echo -n "area[5] = "
echo ${area[5]}
area[6]=`expr ${area[11]} + ${area[51]}`
echo "area[6] = area[11] + area[51]"
echo -n "area[6] = "
echo ${area[6]}
# 这里会失败,是因为不允许整数与字符串相加。
echo; echo; echo
# -----------------------------------------------------------------
# 另一个数组, "area2".
# 另一种给数组变量赋值的方法...
# array_name=( XXX YYY ZZZ ... )
area2=( zero one two three four )
echo -n "area2[0] = "
echo ${area2[0]}
# 啊哈,从0开始计算数组下标(也就是,数组的第一个元素为[0],而不是[1]).
echo -n "area2[1] = "
echo ${area2[1]} # [1] 是数组的第二个元素。
# -----------------------------------------------------------------
echo; echo; echo
# -----------------------------------------------
# 第三个数组, "area3".
# 另外一种给数组元素赋值的方法...
# array_name=([xx]=XXX [yy]=YYY ...)
area3=([17]=seventeen [24]=twenty-four)
echo -n "area3[17] = "
echo ${area3[17]}
echo -n "area3[24] = "
echo ${area3[24]}
# -----------------------------------------------
exit 0我们可以看出,初始化整数的一个简单的方法是 array=( element1 element2 ... elementN ) 。
Bash 允许把变量当成数据来操作,即使这个变量没有明确地被声明为数组。
类似的示范可以参考 Bash变量是无类型的 。
例子 27-2. 格式化一首诗
数组元素有它们独特的语法,甚至标准Bash命令和操作符,都有特殊的选项用以配合数组操作。
例子 27-3. 多种数组操作
大部分标准字符串操作 都可以用于数组中。
例子27-4. 用于数组的字符串操作
命令替换 可以构造数组的独立元素。
例子 27-5. 将脚本中的内容赋值给数组
在数组环境中,某些Bash 内建命令 的含义可能会有些轻微的改变。比如,unset 命令可以删除数组元素,甚至能够删除整个数组。
例子 27-6. 一些数组的专有特性
正如我们在前面的例子中所看到的,${array_name[@]} 或者 ${array_name[*]} 都与数组中的所有元素相关。同样的,为了计算数组的元素个数,可以使用 ${array_name[@]} 或者 ${array_name[*]} 。 ${#array_name} 是数组第一个元素的长度,也就是 ${array_name[0]} 的长度(字符个数)。
例子 27-7. 空数组与包含空元素的数组
${array_name[@]} 和 ${array_name[*]} 的关系非常类似于 $@ 和$*。这种数组用法非常广泛。
array=( element1 element2 ... elementN ) 初始化操作,如果有命令替换的帮助,就可以将一个文本文件的内容加载到数组。
出色的技巧使得数组的操作技术又多了一种。
例子 27-8. 初始化数组
在数组声明的时候添加一个额外的declare -a语句,能够加速后续的数组操作速度。
例子 27-9. 拷贝和连接数组
例子27-10. 关于串联数组的更多信息
有了数组, 我们就可以在脚本中实现一些比较熟悉的算法. 这么做, 到底是不是一个好主意, 我们在这里不做讨论, 还是留给读者决定吧.
例子 27-11. 冒泡排序
我们可以在数组中嵌套数组么?
如果将“嵌套数组”与间接引用 组合起来使用的话,将会产生一些非常有趣的用法。
例子 27-12. 嵌套数组与间接引用
数组使得埃拉托色尼素数筛子有了shell版本的实现. 当然, 如果你需要的是追求效率的应用, 那么就 应该使用编译行语言来实现, 比如C语言. 因为脚本运行的太慢了.
例子 27-13. 埃拉托色尼素数筛子
例子 27-14. 埃拉托色尼素数筛子,优化版
上边的这个例子是基于数组的素数产生器, 还有不使用数组的素数产生器例子A-15 和例子 16-46,让我们来比较一番.
数组可以进行一定程度上的扩展, 这样就可以模拟一些Bash原本不支持的数据结构.
例子 27-15. 模拟一个压入栈
如果想对数组"下标"做一些比较诡异的操作, 可能需要使用中间变量. 对于那些有这种需求的项目来说, 还是应该考虑使用功能更加强大的编程语言, 比如Perl或C。
例子 27-16. 复杂的数组应用: 探索一个神秘的数学序列
Bash仅仅支持一维数组, 但是我们可以使用一个小手段, 这样就可以模拟多维数组了.
例子 27-17. 模拟一个二维数组,并使它倾斜
二维数组本质上其实就是一个一维数组, 只不过是添加了行和列的寻址方式, 来引用和操作数组的元素而已.
这里有一个精心制作的模拟二维数组的例子, 请参考例子 A-10.
还有更多使用数组的有趣的脚本,请参考:
最后更新于
这有帮助吗?