332 lines
8.7 KiB
Markdown
332 lines
8.7 KiB
Markdown
|
<h2><center>Shell 数组</center></h2>
|
|||
|
|
|||
|
------
|
|||
|
|
|||
|
## 一:数组
|
|||
|
|
|||
|
### 1. 介绍
|
|||
|
|
|||
|
Shell 的数组就是把有限个元素(变量或字符内容)用一个名字命名,然后用编号对它们进行区分的元素集合。这个名字就称为数组名,用于区分不同内容的编号就称为数组下标。组成数组的各个元素(变量)称为数组的元素,有时也称为下标变量。有了Shell数组后,就可以用相同名字引用一系列变量及变量值,并通过数字(索引)来识别使用它们。在许多场合,使用数组可以缩短和简化程序开发。数组的本质还是变量,是特殊的变量形式。
|
|||
|
|
|||
|
### 2. 数组分类
|
|||
|
|
|||
|
- **索引数组:**只能使用整数作为数组索引/下标(从0开始)
|
|||
|
- **关联数组:**可以使用字符串作为数组索引/下标
|
|||
|
|
|||
|
### 3. 索引数组
|
|||
|
|
|||
|
#### 数组定义
|
|||
|
|
|||
|
**方法一:**用小括号将变量值括起来赋值给数组变量,每个变量值之间要用空格分隔
|
|||
|
|
|||
|
```bash
|
|||
|
[root@wxin ~]# array=(value1 value2 value3 ... )
|
|||
|
示例:
|
|||
|
[root@wxin ~]# array=(1 2 3) # 用小括号将数组内容赋值给数组变量,数组元素用“空格”分隔开。
|
|||
|
[root@wxin ~]# echo ${array[*]} # 输出上面定义的数组的所有元素值,注意语法。
|
|||
|
1 2 3
|
|||
|
```
|
|||
|
|
|||
|
**方法二:**用小括号将变量值括起来,同时采用键值对的形式赋值
|
|||
|
|
|||
|
```bash
|
|||
|
[root@wxin ~]# array=([0]=one [1]=two [2]=three [3]=four)
|
|||
|
```
|
|||
|
|
|||
|
**方法三:**通过分别定义数组变量的方法来定义
|
|||
|
|
|||
|
```bash
|
|||
|
[root@wxin ~]# array[0]=one
|
|||
|
[root@wxin ~]# array[1]=two
|
|||
|
[root@wxin ~]# array[2]=three
|
|||
|
[root@wxin ~]# array[3]=four
|
|||
|
[root@wxin ~]# echo ${array[@]} # 查看所有数组的值
|
|||
|
one two three four
|
|||
|
```
|
|||
|
|
|||
|
**方法四:**动态地定义数组变量,并使用命令的输出结果作为数组的内容
|
|||
|
|
|||
|
```bash
|
|||
|
array=($(命令))
|
|||
|
array=(`命令`)
|
|||
|
示例:
|
|||
|
[root@wxin ~]# array=(`ls ./`)
|
|||
|
[root@wxin ~]# echo ${array[@]}
|
|||
|
anaconda-ks.cfg initial-setup-ks.cfg 公共 模板 视频 图片 文档 下载 音乐 桌面
|
|||
|
```
|
|||
|
|
|||
|
#### 常用变量
|
|||
|
|
|||
|
```shell
|
|||
|
${ARRAY_NAME[INDEX]} # 引用数组中的元素 注意:引用时,只给数组名,表示引用下标为0的元素
|
|||
|
|
|||
|
${#ARRAY_NAME[*]} # 数组中元素的个数
|
|||
|
${#ARRAY_NAME[@]} # 数组中元素的个数
|
|||
|
|
|||
|
${ARRAY_NAME[*]} # 引用数组中的所有元素
|
|||
|
${ARRAY_NAME[@]} # 引用数组中的所有元素
|
|||
|
|
|||
|
${#ARRAY_NAME} # 数组中下标为 0 的字符个数
|
|||
|
```
|
|||
|
|
|||
|
#### 访问数组
|
|||
|
|
|||
|
```bash
|
|||
|
[root@wxin ~]# array=(one two three four)
|
|||
|
|
|||
|
[root@wxin ~]# echo ${array} 打印单个数组元素用${数组名[下标]},当未指定数组下标时,数组的下标是从0开始。
|
|||
|
one
|
|||
|
[root@wxin ~]# echo ${array[0]}
|
|||
|
one
|
|||
|
|
|||
|
[root@wxin ~]# echo ${array[*]} # 使用*或者@可以得到整个数组内容。
|
|||
|
one two three four
|
|||
|
[root@wxin ~]# echo ${array[@]}
|
|||
|
one two three four
|
|||
|
|
|||
|
[root@wxin ~]# echo ${#array[*]} # 用${#数组名[@或*]}可以得到数组长度,这和前文讲解的变量子串知识是一样的,因为数组也是变量,只不过是特殊的变量,因此也适合变量的子串替换等知识。
|
|||
|
4
|
|||
|
[root@wxin ~]# echo ${#array[@]}
|
|||
|
4
|
|||
|
```
|
|||
|
|
|||
|
#### 数组赋值
|
|||
|
|
|||
|
直接通过`数组名[下标]`对数组进行引用赋值,如果下标不存在,自动添加新一个数组元素,如果下标存在就覆盖原来的值
|
|||
|
|
|||
|
数组中元素的赋值方式主要有几个方式:
|
|||
|
|
|||
|
```bash
|
|||
|
# 一次只能赋值一个元素
|
|||
|
[root@wxin ~]# array[index]=value
|
|||
|
|
|||
|
# 一次赋值全部元素
|
|||
|
[root@wxin ~]# array=("value1" "value2" "value3" ...)
|
|||
|
|
|||
|
# 只赋值特定元素
|
|||
|
[root@wxin ~]# array=([0]="value1" [3]="value2" ...)
|
|||
|
|
|||
|
# 交互式赋值
|
|||
|
[root@wxin ~]# read -a array
|
|||
|
```
|
|||
|
|
|||
|
#### 删除数组
|
|||
|
|
|||
|
因为数组本质上还是变量,因此可通过`unset 数组[下标]`清除相应的数组元素,如果不带下标,表示清除整个数组的所有数据
|
|||
|
|
|||
|
```bash
|
|||
|
[root@wxin ~]# echo ${array[@]}
|
|||
|
anaconda-ks.cfg initial-setup-ks.cfg 公共 模板 视频 图片 文档 下载 音乐 桌面
|
|||
|
[root@wxin ~]# echo ${array[*]}
|
|||
|
anaconda-ks.cfg initial-setup-ks.cfg 公共 模板 视频 图片 文档 下载 音乐 桌面
|
|||
|
[root@wxin ~]# unset array[0]
|
|||
|
[root@wxin ~]# echo ${array[*]}
|
|||
|
initial-setup-ks.cfg 公共 模板 视频 图片 文档 下载 音乐 桌面
|
|||
|
[root@wxin ~]# unset array
|
|||
|
[root@wxin ~]# echo ${array[*]}
|
|||
|
```
|
|||
|
|
|||
|
#### 数组元素删除
|
|||
|
|
|||
|
```bash
|
|||
|
[root@wxin ~]# array=(one two three four five)
|
|||
|
[root@wxin ~]# echo ${array[@]}
|
|||
|
one two three four five
|
|||
|
[root@wxin ~]# echo ${array[@]#*o} # 从每个元素的左边开始匹配最短的,并删除。
|
|||
|
ne three ur five
|
|||
|
[root@wxin ~]# echo ${array[@]##*e} # 从每个元素的左边左边开始匹配最长的,并删除。
|
|||
|
two four
|
|||
|
[root@wxin ~]# echo ${array[@]%f*} # 从每个元素的右边开始匹配最短的,并删除。
|
|||
|
one two three
|
|||
|
[root@wxin ~]# echo ${array[@]%%f*} # 从每个元素的右边开始匹配最长的,并删除。
|
|||
|
one two three
|
|||
|
```
|
|||
|
|
|||
|
#### 数组截取/切片
|
|||
|
|
|||
|
```bash
|
|||
|
命令格式:
|
|||
|
${array_name[@]:offset:number}
|
|||
|
# offset: 要路过的元素个数
|
|||
|
# number: 要取出的元素个数;省略number时,表示取偏移量之后的所有元素
|
|||
|
|
|||
|
|
|||
|
[root@wxin ~]# array=(1 2 3 4 5)
|
|||
|
[root@wxin ~]# echo ${array[@]:1:3} # 从下标为1的元素开始截取,共取3个数组元素
|
|||
|
2 3 4
|
|||
|
|
|||
|
[root@wxin ~]# array=({a..z})
|
|||
|
[root@wxin ~]# echo ${array[@]}
|
|||
|
a b c d e f g h i j k l m n o p q r s t u v w x y z
|
|||
|
[root@wxin ~]# echo ${array[@]:3:3} # 从下标为3的元素开始截取,共取3个数组元素。
|
|||
|
d e f
|
|||
|
[root@wxin ~]# echo ${array[@]:0:3} # 从下标为0的元素开始截取,共取3个数组元素
|
|||
|
a b c
|
|||
|
```
|
|||
|
|
|||
|
#### 数组替换
|
|||
|
|
|||
|
```bash
|
|||
|
[root@wxin ~]# array=(1 2 3 4)
|
|||
|
[root@wxin ~]# echo ${array[@]}
|
|||
|
1 2 3 4
|
|||
|
[root@wxin ~]# echo ${array[@]/2/baby} # 把数组中的2替换成baby,原数组未被修改。
|
|||
|
1 baby 3 4
|
|||
|
```
|
|||
|
|
|||
|
### 4. 遍历数组
|
|||
|
|
|||
|
**`for`循环**
|
|||
|
|
|||
|
```bash
|
|||
|
[root@wxin ~]# array=(one two three four five)
|
|||
|
[root@wxin ~]# for item in "${array[@]}"; do
|
|||
|
> echo "$item"
|
|||
|
> done
|
|||
|
one
|
|||
|
two
|
|||
|
three
|
|||
|
four
|
|||
|
five
|
|||
|
|
|||
|
[root@wxin ~]# for((i=0;i<${#array[@]};i++)); do
|
|||
|
> echo ${array[i]}
|
|||
|
> done
|
|||
|
one
|
|||
|
two
|
|||
|
three
|
|||
|
four
|
|||
|
five
|
|||
|
```
|
|||
|
|
|||
|
**`while`循环**
|
|||
|
|
|||
|
```bash
|
|||
|
[root@wxin ~]# i=0
|
|||
|
[root@wxin ~]# while [ $i -lt ${#array[@]} ]; do
|
|||
|
> echo ${array[$i]}
|
|||
|
> let i++
|
|||
|
> done
|
|||
|
one
|
|||
|
two
|
|||
|
three
|
|||
|
four
|
|||
|
five
|
|||
|
|
|||
|
[root@wxin ~]# i=0
|
|||
|
[root@wxin ~]# while [[ i -lt ${#array[@]} ]]; do
|
|||
|
> echo ${array[i]}
|
|||
|
> let i++
|
|||
|
> done
|
|||
|
```
|
|||
|
|
|||
|
### 4. 关联数组
|
|||
|
|
|||
|
Bash 支持关联数组,它可以使用字符串作为数组索引,关联数组一定要事先声明才行,不然会按照索引数组进行执行
|
|||
|
|
|||
|
#### 定义关联数组
|
|||
|
|
|||
|
**使用声明语句将一个变量声明为关联数组**。
|
|||
|
|
|||
|
```bash
|
|||
|
[root@wxin ~]# declare -A assArray
|
|||
|
```
|
|||
|
|
|||
|
利用内嵌索引-值列表的方法
|
|||
|
|
|||
|
```bash
|
|||
|
[root@wxin ~]# assArray=([lucy]=beijing [yoona]=shanghai)
|
|||
|
[root@wxin ~]# echo ${assArray[lucy]}
|
|||
|
beijing
|
|||
|
```
|
|||
|
|
|||
|
使用独立的索引-值进行赋值
|
|||
|
|
|||
|
```bash
|
|||
|
[root@wxin ~]# assArray[lily]=shandong
|
|||
|
[root@wxin ~]# assArray[sunny]=xian
|
|||
|
[root@wxin ~]# echo ${assArray[sunny]}
|
|||
|
xian
|
|||
|
[root@wxin ~]# echo ${assArray[lily]}
|
|||
|
shandong
|
|||
|
```
|
|||
|
|
|||
|
#### 列出数组索引
|
|||
|
|
|||
|
每一个数组都有一个索引用于查找。使用${!数组名[@或者*]}获取数组的索引列表
|
|||
|
|
|||
|
```bash
|
|||
|
[root@wxin ~]# echo ${!assArray[*]}
|
|||
|
lily yoona sunny lucy
|
|||
|
[root@wxin ~]# echo ${!assArray[@]}
|
|||
|
lily yoona sunny lucy
|
|||
|
```
|
|||
|
|
|||
|
#### 获取所有键值对
|
|||
|
|
|||
|
```bash
|
|||
|
[root@wxin ~]# vim assArray.sh
|
|||
|
#!/bin/bash
|
|||
|
declare -A cityArray
|
|||
|
cityArray=([yoona]=beijing [lucy]=shanghai [lily]=shandong)
|
|||
|
for key in ${!cityArray[@]}; do
|
|||
|
echo "$key come from ${cityArray[$key]}"
|
|||
|
done
|
|||
|
|
|||
|
|
|||
|
[root@wxin ~]# bash assArray.sh
|
|||
|
lily come from shandong
|
|||
|
yoona come from beijing
|
|||
|
lucy come from shanghai
|
|||
|
```
|
|||
|
|
|||
|
**示例1:**使用循环批量输出数组的元素
|
|||
|
|
|||
|
```bash
|
|||
|
#!/bin/bash
|
|||
|
array=(1 2 3 4 5)
|
|||
|
for i in ${array[@]}; do
|
|||
|
echo $i
|
|||
|
done
|
|||
|
|
|||
|
array1=(1 2 3 4 5)
|
|||
|
for ((i=0;i<${#array1[@]};i++)); do
|
|||
|
echo ${array[i]}
|
|||
|
done
|
|||
|
|
|||
|
array2=(1 2 3 4 5)
|
|||
|
i=0
|
|||
|
while ((i<${#array2[@]})); do
|
|||
|
echo ${array2[i]}
|
|||
|
let i++
|
|||
|
done
|
|||
|
```
|
|||
|
|
|||
|
**示例2:**通过竖向列举法定义数组元素并批量打印
|
|||
|
|
|||
|
```bash
|
|||
|
#!/bin/bash
|
|||
|
array=(one two three four five)
|
|||
|
for ((i=0;i<${#array[@]};i++)); do
|
|||
|
echo "This is num $i, then content is ${array[i]}"
|
|||
|
done
|
|||
|
```
|
|||
|
|
|||
|
**示例3:**把命令结果作为数组元素定义并打印
|
|||
|
|
|||
|
```bash
|
|||
|
#!/bin/bash
|
|||
|
array=(`ls ./`)
|
|||
|
for ((i=0;i<${#array[@]};i++)); do
|
|||
|
echo "This is num $i, then content is ${array[i]}"
|
|||
|
done
|
|||
|
echo ==========================================
|
|||
|
array2=(`ls ./`)
|
|||
|
num=1
|
|||
|
for i in ${array[@]}; do
|
|||
|
echo "This is num $num, then content is $i"
|
|||
|
let num++
|
|||
|
done
|
|||
|
```
|
|||
|
|