创建数组

数组可以采用逐个赋值的方法创建。

1
ARRAY[INDEX]=value

上面语法中,ARRAY是数组的名字,可以是任意合法的变量名。INDEX是一个大于或等于零的整数,也可以是算术表达式。注意数组第一个元素的下标是 0, 而不是 1。

下面创建一个三个成员的数组。

1
2
3
$ array[0]=val
$ array[1]=val
$ array[2]=val

数组也可以采用一次性赋值的方式创建。

1
2
3
4
5
6
7
8
ARRAY=(value1 value2 ... valueN)

# 等同于
ARRAY=(
value1
value2
value3
)

采用上面方式创建数组时,可以按照默认顺序赋值,也可以在每个值前面指定位置。

1
2
3
4
5
$ array=(a b c)
$ array=([2]=c [0]=a [1]=b)

$ days=(Sun Mon Tue Wed Thu Fri Sat)
$ days=([0]=Sun [1]=Mon [2]=Tue [3]=Wed [4]=Thu [5]=Fri [6]=Sat)

只为某些值指定位置,也是可以的。

1
names=(hatter [5]=duchess alice)

上面例子中,hatter是数组的 0 号位置,duchess是 5 号位置,alice是 6 号位置。

没有赋值的数组元素的默认值是空字符串。

定义数组的时候,可以使用通配符。

1
$ mp3s=( *.mp3 )

上面例子中,将当前目录的所有 MP3 文件,放进一个数组。

先用declare -a命令声明一个数组,也是可以的。

1
$ declare -a ARRAYNAME

read -a命令则是将用户的命令行输入,存入一个数组。

1
$ read -a dice

上面命令将用户的命令行输入,存入数组dice

读取数组

读取单个元素

读取数组指定位置的成员,要使用下面的语法。

1
$ echo ${array[i]}     # i 是索引

上面语法里面的大括号是必不可少的,否则 Bash 会把索引部分[i]按照原样输出。

1
2
3
4
5
6
7
$ array[0]=a

$ echo ${array[0]}
a

$ echo $array[0]
a[0]

上面例子中,数组的第一个元素是a。如果不加大括号,Bash 会直接读取$array首成员的值,然后将[0]按照原样输出。

读取所有成员

@*是数组的特殊索引,表示返回数组的所有成员。

1
2
3
$ foo=(a b c d e f)
$ echo ${foo[@]}
a b c d e f

这两个特殊索引配合for循环,就可以用来遍历数组。

1
2
3
for i in "${names[@]}"; do
echo $i
done

@*放不放在双引号之中,是有差别的。

1
2
3
4
5
6
7
8
9
10
11
12
13
$ activities=( swimming "water skiing" canoeing "white-water rafting" surfing )
$ for act in ${activities[@]}; \
do \
echo "Activity: $act"; \
done

Activity: swimming
Activity: water
Activity: skiing
Activity: canoeing
Activity: white-water
Activity: rafting
Activity: surfing

上面的例子中,数组activities实际包含 5 个成员,但是for...in循环直接遍历${activities[@]},导致返回 7 个结果。为了避免这种情况,一般把${activities[@]}放在双引号之中。

1
2
3
4
5
6
7
8
9
10
$ for act in "${activities[@]}"; \
do \
echo "Activity: $act"; \
done

Activity: swimming
Activity: water skiing
Activity: canoeing
Activity: white-water rafting
Activity: surfing

上面例子中,${activities[@]}放在双引号之中,遍历就会返回正确的结果。

${activities[*]}不放在双引号之中,跟${activities[@]}不放在双引号之中是一样的。

1
2
3
4
5
6
7
8
9
10
11
12
$ for act in ${activities[*]}; \
do \
echo "Activity: $act"; \
done

Activity: swimming
Activity: water
Activity: skiing
Activity: canoeing
Activity: white-water
Activity: rafting
Activity: surfing

${activities[*]}放在双引号之中,所有成员就会变成单个字符串返回。

1
2
3
4
5
6
$ for act in "${activities[*]}"; \
do \
echo "Activity: $act"; \
done

Activity: swimming water skiing canoeing white-water rafting surfing

所以,拷贝一个数组的最方便方法,就是写成下面这样。

1
$ hobbies=( "${activities[@]}" )

上面例子中,数组activities被拷贝给了另一个数组hobbies

这种写法也可以用来为新数组添加成员。

1
$ hobbies=( "${activities[@]}" diving )

上面例子中,新数组hobbies在数组activities的所有成员之后,又添加了一个成员。

默认位置

如果读取数组成员时,没有读取指定哪一个位置的成员,默认使用 0 号位置。

1
2
3
4
$ declare -a foo
$ foo=A
$ echo ${foo[0]}
A

上面例子中,foo是一个数组,赋值的时候不指定位置,实际上是给foo[0]赋值。

引用一个不带下标的数组变量,则引用的是 0 号位置的数组元素。

1
2
3
4
5
$ foo=(a b c d e f)
$ echo ${foo}
a
$ echo $foo
a

上面例子中,引用数组元素的时候,没有指定位置,结果返回的是 0 号位置。

数组的长度

要想知道数组的长度(即一共包含多少成员),可以使用下面两种语法。

1
2
${#array[*]}
${#array[@]}

下面是一个例子。

1
2
3
4
5
6
7
$ a[100]=foo

$ echo ${#a[*]}
1

$ echo ${#a[@]}
1

上面例子中,把字符串赋值给 100 位置的数组元素,这时的数组只有一个元素。

注意,如果用这种语法去读取具体的数组成员,就会返回该成员的字符串长度。这一点必须小心。

1
2
3
$ a[100]=foo
$ echo ${#a[100]}
3

上面例子中,`$

打赏

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2017-2023 WSQ
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信