UNIX/Linux系统管理技术手册(3)----bash 数组和算术运算

  复杂的数据结构和计算不是 bash 的特长。但它的确至少提供了数组和算术运算。

1.算术运算

  所有的 bash 变量的值都是字符串,所以 bash 在赋值的时候并不区分数字 1 和 字符串 "1" 。不同之处在于如何使用变量。下面几行代码展示出了其中的差异:

#!/bin/bash

a=1
b=$((2))
c=$a+$b
d=$(($a+$b))

echo "$a + $b = $c \t(plus sign as string literal)"
echo "$a + $b = $d \t(plus sign as arithmetic addition)"

运行结果:

root@javis:~/Documents/bash$ ./array.sh 
1 + 2 = 1+2 \t(plus sign as string literal)
1 + 2 = 3 \t(plus sign as arithmetic addition)

  注意给$c 赋值的语句,其中的加号(+) 连字符串的连接运算符都不是。它仅仅就是一个字符而已。那行代码等价于:

c="$a+$b"

  为了强制进行数值计算,要把这个表达式放在 $((...))里面,就像上面给 $d 赋值一样。但即便如此,也不会让 $d 获得一个数值;它的值让然保存为字符串 "3" 。

 

2.数组运算

  数组用括号括起来,数组元素之间用空白隔开。数组元素中的空白要用引号引起来。

example=(aa  'bb cc'  dd)

  单个数组元素用 ${array_name[subscript]}来访问。下标从 0 开始。下标 * 和 @ 指整个数组,${#array_name[*]}和${#array_name[@]}这两种特殊形式表示数组里元素的个数。不要把它们和似乎更合乎逻辑的${#array_name}搞混了;后者实际上是数组第一个元素的长度(等价于${#array_name[0]})。

  $array_name[1] 容易让人以为是指数组的第二个元素,这一点无可争议,但 bash 对这个字符串的分析结果却是:$array_name 加上一个字符串 [1]。在访问数组变量的时候,一定要带花括号----这一点无一例外。

  下面是一个快速脚本,它演示了 bash 中数组管理的一些功能和缺陷:

#!/bin/bash
example=(aa 'bb cc' dd)
example[3]=ee
echo "example[@] = ${example[@]}"
echo "example array contains ${#example[@]} elements"
for elt in "${example[@]}"; do
        echo "Element = $elt"
done

运行结果:

root@javis:~/Documents/bash$ sh array1.sh
example[@] = aa bb cc dd ee
example array contains 4 elements
Element = aa
Element = bb cc
Element = dd
Element = ee

如果用下面这一句代码替换 for 语句那一行代码:

for elt in ${example[@]} ; do

这也可以执行,但它却不是输出4个数组元素,而是5个: aa 、bb、cc、dd 和 ee。

  这个问题的背后,是因为所有的 bash 变量实质上仍是字符串,所以数组的表象充其量还是不确定的。字符串什么时候分割成数字元素,怎样分割成数组元素,都有很细微的变化。可以使用 Perl 或者 Python 来研究这些细微的差别。

 

posted @ 2016-07-19 17:28  HorseShoe2016  阅读(278)  评论(0编辑  收藏  举报