文章目录

数组

一 、数组介绍

1、什么是数组?

数组就是一系列元素的集合,一个数组内可以存放多个元素

2、为何要用数组?

我们可以用数组将多个元素汇总到一起,避免单独定义的麻烦

二 、数组的使用

1、 数组的定义

# 方式一:array=(元素1 元素2 元素3)
array=(mm 18 male)

# 方式二:array=([key1]=value1 [key2]=value2 [key3]=value3)
array=([0]=111 [1]="two" [2]=333)

# 方式三:依次赋值
array_new[0]=111
array_new[1]=222
array_new[2]="third"

# 方式四:利用执行命令的结果设置数组元素:array=($(命令)) 或者 array=(`命令`)
该方式会将命令的结果以空格为分隔符切成多个元素然后赋值给数组
[root@openvpn ~]# ls /test
a.txt b.txt
[root@openvpn ~]# array3=(`ls /test`)
[root@openvpn ~]# declare -a |grep array3
declare -a array3='([0]="a.txt" [1]="b.txt")'


# ps:查看声明过的数组
declare -a

[root@openvpn day7]# x=(1 233 41)
[root@openvpn day7]# echo ${x[0]}
1
[root@openvpn day7]# echo ${!x[@]}
0 1 2
# 取数组的索引

2、 访问数组内元素

[root@openvpn ~]# array=(mm 18 male)

#1、按照索引访问数组内指定位置的元素
[root@openvpn ~]# echo ${array[0]}
mm
[root@openvpn ~]# echo ${array[1]}
18
[root@openvpn ~]# echo ${array[2]}
male
[root@openvpn ~]# echo ${array[-1]} # 支持负向索引
male


# 2、访问数组内全部元素信息
[root@openvpn ~]# echo ${array[*]}
mm 18 male
[root@openvpn ~]# echo ${array[@]}
mm 18 male

# 3、获取数组元素的长度
[root@openvpn ~]# echo ${#array[*]}
3
[root@openvpn ~]# echo ${#array[@]}
3

[root@openvpn ~]# declare -a mm='([0]="gril")'
[root@openvpn ~]# echo ${#mm[*]}
4

3、实例

# for循环查看ls/root/下的文件
[root@openvpn day7]# cat arr.sh
#! /bin/bash
declare -a arr=(`ls /root`)

for i in ${arr[*]}
do
echo $i
done
[root@openvpn day7]# ./arr.sh
anaconda-ks.cfg
dead.letter
hosts.sh
shell
ssh-jump.sh
# while 循环
[root@openvpn day7]# cat arr1.sh
num=#{#arr[*]}
while (( $num > 0 ))
do
echo ${arr[$num]}
let num--
done

4 、获取数组元素

# 默认遍历获取下标为0的数据
echo $arr

# 正向获取从0开始,反向获取从-1开始

# 获取所有的值
${arr[*]}
${arr[@]}

5、修改/添加数组元素

[root@openvpn ~]# array=(mm 18 male)
[root@openvpn ~]# array[0]="mm" # 修改
[root@openvpn ~]# array[3]="IT" # 添加
[root@openvpn ~]# declare -a |grep array
declare -a array='([0]="mm" [1]="18" [2]="male" [3]="IT")'
# 存在的下标及修改,不存在的下标及添加

5、 删除数组元素

[root@openvpn ~]# unset array[0]
[root@openvpn ~]# echo ${array[*]}
18 male IT
[root@openvpn ~]# declare -a |grep array
declare -a array='([1]="18" [2]="male" [3]="IT")'
[root@openvpn ~]#
[root@openvpn ~]#
[root@openvpn ~]# unset array[2]
[root@openvpn ~]# declare -a |grep array
declare -a array='([1]="18" [3]="IT")'

[root@openvpn ~]# unset array # 删除整个数组
[root@openvpn ~]# echo ${array[*]}

# 指定下标则删除某一个值,不指定下标则删除所有的值

6、 数组内元素的截取

# 截取某一个值
[root@openvpn ~]# array=(mm 18 male IT 1.80)
[root@openvpn ~]# echo ${array[*]:1} # 从索引1开始,一直到最后
18 male IT 1.80
[root@openvpn ~]# echo ${array[*]:1:3} # 从索引1开始,访问3个元素
18 male IT
# 截取某部分值
[root@openvpn ~]# array=(one two three four five fire)
[root@openvpn ~]# echo ${array[*]#one}
two three four five fire
[root@openvpn ~]# echo ${array[*]#f*e}
one two three four

7、 数组内容的替换

[root@openvpn ~]# array=(one two three four five fire)

[root@openvpn ~]# echo ${array[*]/five/abc}
one two three four abc fire

[root@openvpn ~]# echo ${array[*]/f*e/abc}
one two three four abc abc

三、 关联数组

1、数组分为两种

- 普通数组:只能使用整数作为数组索引,我们前面介绍的都是普通数组
- 关联数组:可以使用字符串作为数组索引,需要用declare -A 声明

2、声明关联数组

[root@openvpn ~]# declare -A info
[root@openvpn ~]# info["name"]="mm"
[root@openvpn ~]# info["age"]=18
[root@openvpn ~]# info["gender"]="male"
[root@openvpn ~]# declare -A |grep info
declare -A info='([gender]="male" [name]="mm" [age]="18" )'
[root@openvpn ~]#
[root@openvpn ~]# echo ${info[*]}
male mm 18
[root@openvpn ~]# echo ${info["name"]}
mm
#方式二
[root@openvpn day7]# declare -A array=(["name"]=mm)
#方式三
[root@openvpn day7]# declare -A array
[root@openvpn day7]# array['name']=shanhe

四 、遍历数组

方法一:

利用获取所有信息进行遍历 (适用于普通数组与关联数组)

# 例1
declare -A array
array=(["name"]="mm" ["age"]=18 ["gender"]="male")

for item in ${array[*]}
do
echo $item
done

# 例2
array=("mm" 18 "male")
for item in ${array[*]}
do
echo $item
done

1、遍历key
#!/bin/bash
declare -A array=([name]="shanhe" )
for i in ${!array[*]}
do
echo $i
done

2、遍历值
#!/bin/bash
declare -A array=([name]="shanhe" )
for i in ${array[*]}
do
echo $i
done

方法二:

通过数组元数的索引进行遍历(适用于普通数组与关联数组)

# 例1
declare -A array
array=(["name"]="mm" ["age"]=18 ["gender"]="male")

for i in ${!array[*]} # echo ${!array[*]} # 获取的是key信息:name age gender
do
echo "$i:${array[$i]}"
done

# 例2
array=("mm" 18 "male")
for i in ${!array[*]} # echo ${!array[*]} 直接获取所有元素的索引信息
do
echo $i
echo ${array[i]}
done

# 例3
[root@openvpn day7]# cat arr3.sh
#! /bin/bash

declare -A m
m["name"]=mm
m["age"]=18
m["sex"]=man

for i in ${m[*]}
do
echo $i
done
[root@openvpn day7]# ./arr3.sh
mm
18
man

方法三:

根据数组长度信息进行遍历,(适用于普通数组)

# 遍历数组: 按照索引累加变量
array=("mm" 18 "male")

for ((i=0;i<${#array[*]};i++))
do
echo "$i:${array[$i]}"
done
# 方式二

[root@openvpn day7]# cat array.sh
#! /bin/bash

array1=(111 2222 433)

for ((i=0;i<${#array1[*]};i++))
do
echo ${array1[$i]}
done
[root@openvpn day7]# ./array.sh
111
2222
433

五 、练习

练习1:

对指定的IP地址进行网络测试

[root@openvpn day7]# cat arr4.sh 
#! /bin/bash
declare -a ip=({1..254})
for i in ${ip[*]}
do
(ping -c1 -t1 192.168.15.$i &> /dev/null
if [ $? -eq 0 ];then
echo "192.168.15.$i up"
else
echo "192.168.15.$i down"
fi)&
done
# 方式二
#!/bin/bash
array=(
10.0.0.7
10.0.0.8
10.0.0.9
10.0.0.41
)

for info in ${array[*]}
do
ping -c 2 -W 1 $info
done

练习2:

统计登录shell的种类及对应的个数(关联数组)

#!/bin/bash 
declare -A array_for_shell
while read line # done后面接<将文件重定向给while;while后再接read将文件流赋值给变量
do
login_shell=`echo $line | cut -d: -f7`
let array_for_shell["$login_shell"]++ # 当使用let时,变量前面不必加上$
done < /etc/passwd


for k in ${!array_for_shell[*]}
do
echo $k:${array_for_shell[$k]}
done

练习3:

获取文件指定列的信息

[root@mm test]# cat a.sh 
#!/usr/bin/env bash

declare -A array
while read line
do
let array[`echo $line | cut -d: -f7`]++
done < /etc/passwd

for k in ${!array[*]}
do
echo $k:${array[$k]}
done
[root@mm test]#
[root@mm test]# ./a.sh
/sbin/nologin:41
/bin/sync:1
/bin/bash:2
/sbin/shutdown:1
/sbin/halt:1

练习4

[root@openvpn day7]# cat array1.sh 
#! /bin/bash

declare -A array1=(["name"]="mm" ["age"]=18 ["gender"]="male")
for i in ${array1[*]}
do
echo $i
done

echo "==============="
for item in ${!array1[*]}
do
echo $item
done
[root@openvpn day7]# ./array1.sh
male
mm
18
===============
gender
name
age

练习5

打印/ect/passwd/最后一行

# 方式一 for循环
[root@openvpn day7]# cat arr5.sh
#! /bin/bash

for i in `tail /etc/passwd |awk -F: '{print $NF}'`
do
echo $i
done
[root@openvpn day7]# ./arr5.sh
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/bash
# 方式二 while循环
[root@openvpn day7]# cat arr6.sh
#! /bin/bash

while read line
do
i=`echo $line |awk -F: '{print $NF}'`
echo $i
done < tail /etc/passwd
[root@openvpn day7]# ./arr6.sh
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/bash