mirror of
https://github.com/wangdoc/bash-tutorial.git
synced 2025-12-20 02:18:48 +08:00
docs: edit array
This commit is contained in:
144
docs/array.md
144
docs/array.md
@@ -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
|
||||
```
|
||||
|
||||
@@ -178,6 +178,15 @@ unset NAME
|
||||
|
||||
这个命令不是很有用。因为不存在的 Bash 变量一律都等于空字符串,所以即使`unset`命令删除了变量,还是可以读取这个变量,值为空字符串。
|
||||
|
||||
所以,删除一个变量,也可以将这个变量设成空字符串。
|
||||
|
||||
```bash
|
||||
$ foo=''
|
||||
$ foo=
|
||||
```
|
||||
|
||||
上面两种写法,都是删除了变量`foo`。
|
||||
|
||||
## 输出变量
|
||||
|
||||
像上一节那样创建的变量,都是局部变量,仅可用于当前 Shell,当前 Shell 的子 Shell 读取不到此变量。为了把变量传递到子 Shell,需要使用`export`命令。这样输出的变量,对于子 Shell 来说就是环境变量。
|
||||
|
||||
Reference in New Issue
Block a user