docs: edit array

This commit is contained in:
ruanyf
2020-03-29 00:25:27 +08:00
parent dc9098d2eb
commit e5f1fc634a
2 changed files with 149 additions and 4 deletions

View File

@@ -26,10 +26,26 @@ $ array[2]=val
$ declare -a ARRAYNAME
```
`read -a`命令也可以将命令行输入,读入一个数组。
```bash
$ read -a dice
```
上面命令将用户的命令行输入,读入数组`dice`
数组也可以采用一次性赋值的方式创建。
```bash
ARRAY=(value1 value2 ... valueN)
# 等同于
ARRAY=(
value1
value2
value3
)
```
采用上面方式创建数组时,可以按照默认顺序赋值,也可以在每个值前面指定位置。
@@ -52,6 +68,14 @@ names=(hatter [5]=duchess alice)
没有赋值的数组元素是不存在的,默认值是空字符串。
定义数组的时候,可以使用通配符。
```bash
$ mp3s=( *.mp3 )
```
上面例子中,将当前目录的所有 MP3 文件,放进一个数组。
在数组末尾附加数据,可以使用`+=`赋值运算符,能够自动地把值附加到数组末尾。否则,还需要知道数组的最大位置,这就比较麻烦。
```bash
@@ -66,6 +90,8 @@ a b c d e f
## 读取数组
### 读取单个元素
读取数组指定位置的成员,要使用下面的语法。
```bash
@@ -86,6 +112,8 @@ a[0]
上面例子中,数组的第一个元素是`a`。如果不加大括号Bash 会直接读取`$array`的值,然后将`[0]`按照原样输出。
### 读取所有成员
`@``*`是数组的特殊索引,表示返回数组的所有成员。
```bash
@@ -102,6 +130,87 @@ for i in "${names[@]}"; do
done
```
`@``*`放不放在双引号之中,是有差别的。
```bash
$ 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[@]}`放在双引号之中。
```bash
$ 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[@]}`不放双引号是一样的。
```bash
$ 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[*]}`如果放在双引号之中,所有元素就会变成单个字符串返回。
```bash
$ for act in "${activities[*]}"; \
do \
echo "Activity: $act"; \
done
Activity: swimming water skiing canoeing white-water rafting surfing
```
所以,拷贝一个数组的最方便方法,就是写成下面这样。
```bash
$ hobbies=( "${activities[@]}" )
```
上面例子中,数组`activities`被拷贝给了另一个数组`hobbies`
这种写法也可以用来为新数组添加成员。
```bash
$ hobbies=( "${activities[@]" diving )
```
上面例子中,新数组`hobbies`在数组`activities`的所有成员之后,又添加了一个成员。
### 默认位置
如果读取数组成员时,没有读取指定哪一个位置的成员,默认使用`0`号位置。
```bash
@@ -125,7 +234,9 @@ a
上面例子中,引用数组元素的时候,没有指定位置,结果返回的是`0`号位置。
要想直到数组一共包含多少成员,可以使用下面两种语法。
### 数组的长度
要想知道数组的长度(即一共包含多少成员),可以使用下面两种语法。
```bash
${#array[*]}
@@ -146,7 +257,7 @@ $ echo ${#a[@]}
上面例子中,把字符串赋值给`100`位置的数组元素,这时的数组只有一个元素。
注意,如果把上面例子的`*``@`,写成具体的下标,就变成返回字符串长度。
注意,如果用这种语法去读取具体的数组元素,就会返回该元素的字符串长度。这一点必须小心。
```bash
$ a[100]=foo
@@ -154,7 +265,9 @@ $ echo ${#a[100]}
3
```
上面例子中,`${#a[100]}`实际上是返回变量`a[100]`的值`foo`的长度。
上面例子中,`${#a[100]}`实际上是返回变量`a[100]`的值`foo`字符串长度。
### 有值的位置
`${!array[@]}``${!array[*]}`,可以返回数组的哪些位置是有值的。
@@ -178,6 +291,29 @@ for i in ${!arr[@]};do
done
```
## 提取数组元素
`${array[@]:position:length}`的语法可以提取数组元素。
```bash
$ food=( apples bananas cucumbers dates eggs fajitas grapes )
$ echo ${food[@]:1:1}
bananas
$ echo ${food[@]:1:3}
bananas cucumbers dates
```
上面例子中,`${food[@]:1:1}`返回从数组1号位置开始的1个元素`${food[@]:1:3}`返回从1号位置开始的3个元素。
如果省略长度参数,则返回从指定位置开始的所有元素。
```bash
$ echo ${food[@]:4}
eggs fajitas grapes
```
上面例子返回从4号位置开始到结束的所有元素。
## 删除数组
删除一个数组成员,使用`unset`命令。
@@ -187,7 +323,7 @@ $ foo=(a b c d e f)
$ echo ${foo[@]}
a b c d e f
$ unset 'foo[2]'
$ unset foo[2]
$ echo ${foo[@]}
a b d e f
```

View File

@@ -178,6 +178,15 @@ unset NAME
这个命令不是很有用。因为不存在的 Bash 变量一律都等于空字符串,所以即使`unset`命令删除了变量,还是可以读取这个变量,值为空字符串。
所以,删除一个变量,也可以将这个变量设成空字符串。
```bash
$ foo=''
$ foo=
```
上面两种写法,都是删除了变量`foo`
## 输出变量
像上一节那样创建的变量,都是局部变量,仅可用于当前 Shell当前 Shell 的子 Shell 读取不到此变量。为了把变量传递到子 Shell需要使用`export`命令。这样输出的变量,对于子 Shell 来说就是环境变量。