Day05-SHELL自动化编程-数组-三剑客进阶

14 Shell编程-数组

14.1 概述

  • 数组也是一种变量.

  • 数组可以存放多个 相关联内容 ,通过访问数组调用结果(值)

  • 应用场景:用于存放相关的数据。

  • 如何创建数组(手动)

[root@m01 devops-shell]# ip_array=(10.0.0.61 10.0.0.62 10.0.0.63 10.0.0.64)
[root@m01 devops-shell]# echo ${ip_array}
10.0.0.61
[root@m01 devops-shell]# echo ${ip_array[0]}
10.0.0.61
[root@m01 devops-shell]# echo ${ip_array[2]}
10.0.0.63
[root@m01 devops-shell]# echo ${ip_array[*]}
10.0.0.61 10.0.0.62 10.0.0.63 10.0.0.64
[root@m01 devops-shell]# echo ${#ip_array[*]}
4
[root@m01 devops-shell]# for n in ${ip_array[*]}
> do
> echo $n
> done
10.0.0.61
10.0.0.62
10.0.0.63
10.0.0.64
[root@m01 devops-shell]# for((i=0;i<=${#ip_array[*]};i++))  # <=有误
> do
> echo $i ${ip_array[i]}
> done
0 10.0.0.61
1 10.0.0.62
2 10.0.0.63
3 10.0.0.64
4
[root@m01 devops-shell]# for((i=0;i<${#ip_array[*]};i++)); do echo $i ${ip_array[i]}; done
0 10.0.0.61
1 10.0.0.62
2 10.0.0.63
3 10.0.0.64

ip_array数组
ip_array[0] 数组中的某个元素  0表示下标,元素名称

输出数组中所有值

echo ${ip_array[@]}
echo ${ip_array[*]}

计算数组的元素的个数

echo ${#ip_array[@]}
echo ${#ip_array[*]}

课外知识:了解

shell数组,下标或元素名字,默认只能是数字。

要在shell数字中,下标中使用字符串,需要创建关联数组。(awk中使用更多,默认就是这个)

shell数组的循环

推荐的形式

names=(web01 web02 db01 nfs01 backup)
for n  in  ${names[@]}
do
     ping -c 1 -W 1  $n  
done

了解的形式

names=(web01 web02 db01 nfs01 backup)
for((i=0;i<${#names[@]};i++))
do
     ping -c 1 -W 1  ${names[i]}  
done

14.2 Shell数组赋值

shell数组创建(赋值)具体形式应用场景
批量直接赋值array=(ip01 ip02 ip03 ip04 )
array=( 命令结果 ) # cat ip.txt 三剑客命令获取指定内容
应用最多
逐个元素赋值array[0]=lidao array[1]=oldboy array[2]=oldwang
几乎不会使用
read命令赋值read -p “输入数组中内容:” -a array 可以创建数组,空格分割即可用于连续读取数据,用户输入3个数
cat ip.txt
10.0.0.5
10.0.0.6
10.0.0.7
10.0.0.8
10.0.0.9
ip_list=(`cat ip.txt`)
echo ${ip_list[@]}
10.0.0.5 10.0.0.6 10.0.0.7 10.0.0.8 10.0.0.9
echo ${#ip_list[@]}
5

14.3 案例

案例33: 试编写一个Shell程序,该程序能接收用户从键盘输入的10个整数,然后求出其总和、平均值

  • 方法00:
    • 用户输入数字 10个存放变量中或数组中.
    • 存完后,进行计算与统计
[root@m01 devops-shell]# cat 33-calc_num.sh
#!/bin/bash
##############################################################
# File Name:33-calc_num.sh
# Version:V1.0
# Author:oldboy lidao996
# Organization:www.oldboyedu.com
# Desc: 读取用户写入的10个数字,然后计算总和,平均值
##############################################################

tmp_file=${0}_$$.txt

#0.检查输入是否为数字,或q退出
check_num() {
  if [ "$num" = "q" ]
  then
    echo "输入完成,准备进行计算"
    break
  fi
  if [[ ! $num =~ ^[0-9]+$ ]]
  then
    echo "输入异常,请重新输入数字"
    continue
  fi  
}

#1.死循环读取用户输入,按q退出
read_num() {
while :
do
  read -p "请逐个输入数字,完成后按q结束:" num
  check_num
  #需求向变量中追加内容读取变量内容后写入到文件
  echo $num >>$tmp_file
done
}

#2.计算与输出
calc_num() {
  num_array=(`cat $tmp_file`)
  sum=0
  for n in ${num_array[@]}
  do
    let sum=sum+n
  done
  #计算平均值
  clear
  echo "总数:$sum"
  echo "平均值:"
  echo "$sum/${#num_array[@]}" | bc -l
}

#3.main
main() {
  read_num
  calc_num
}
main

[root@m01 devops-shell]# sh 33-calc_num.sh 
请逐个输入数字,完成后按q结束:1
请逐个输入数字,完成后按q结束:2
请逐个输入数字,完成后按q结束:2
请逐个输入数字,完成后按q结束:3
请逐个输入数字,完成后按q结束:
输入异常,请重新输入数字
请逐个输入数字,完成后按q结束:4
请逐个输入数字,完成后按q结束:44
请逐个输入数字,完成后按q结束:4
请逐个输入数字,完成后按q结束:r
输入异常,请重新输入数字
请逐个输入数字,完成后按q结束:er
输入异常,请重新输入数字
请逐个输入数字,完成后按q结束:ewr
输入异常,请重新输入数字
请逐个输入数字,完成后按q结束:r
输入异常,请重新输入数字
请逐个输入数字,完成后按q结束:wwe
输入异常,请重新输入数字
请逐个输入数字,完成后按q结束:rw
e输入异常,请重新输入数字
请逐个输入数字,完成后按q结束:r
输入异常,请重新输入数字
请逐个输入数字,完成后按q结束:wer
输入异常,请重新输入数字
请逐个输入数字,完成后按q结束:23
请逐个输入数字,完成后按q结束:12
请逐个输入数字,完成后按q结束:q
输入完成,准备进行计算
总数:95
平均值:
10.55555555555555555555

精简版read+awk

[root@m01 /server/scripts/devops-shell]# read -p "请输入数字以空格分割:" num
请输入数字以空格分割:12312 5 56 6 67
[root@m01 /server/scripts/devops-shell]# echo $num|xargs -n1|awk '{sum=sum+$1}END{print sum,sum/NR}'
12446 2489.2

14.4 小结

  • 如何赋值(如何创建)(通过命令结果)。
  • 如何取值,统计数组元素的个数。
  • 数组与for循环。
  • 未来常用的是awk数组。

15. Shell-编程-Debug全流程

15.1 书写习惯

书写习惯
注释
变量 :在脚本中尽量使用变量,变量命名规范(给变量加上说明)。
函数 :代码中尽可能使用函数,增加说明。 模块化.
返回值 : 尽可能增加函数return功能,方便后期调试。
参数与选项检查 : 进可能增加exit 返回值的功能,方便后期调试。
书写的时候适当增加 输出 :书写代码的时候,可以多写一些echo用于在某些步骤中进行输出。
缩进 :代码注意缩进。
成对的符号提前输入好. “” [] {}

15.2 调试方法

调试方法说明
-x大部分时候使用:sh /bash -x显示详细的执行过程。
精确显示过程脚本使用functions函数库,脚本过大,可以在脚本中使用
set -x 开始显示详细信息
代码
set +x 关闭显示详细信息
注释法使用函数,注释法。注释多余的函数,排除。缩小范围定位问题
输出关键变量变量后增加echo输出变量内容。查看过程。
  • 大部分时候使用:sh -x显示详细的执行过程。

  • 排除法

16. 再战三剑客

16.1 sed与变量

案例34-sed命令中如何调用变量

cat ip.txt
10.0.0.5
10.0.0.6
10.0.0.7
10.0.0.8
10.0.0.9
src=10.0.0
dst=172.16.1
sed "s#$src#$dst#g" ip.txt
172.16.1.5
172.16.1.6
172.16.1.7
172.16.1.8
172.16.1.9

16.2 awk

1)指哪打哪-案例

案例35-过滤出/etc/passwd的第2到9行的第1列和第3列

awk -F: 'NR>=2 && NR<=9{print $1,$3}' /etc/passwd
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8

案例36-第1列用户名等于root的最后一列(命令解释器)。

awk -F: '$1=="root"{print $NF}' /etc/passwd
/bin/bash
awk -F: '$1==root{print $NF}' /etc/passwd

案例37-进阶:第1列用户名等于root的最后一列(命令解释器)。 使用变量方法

[root@m01 devops-shell]# name=root
[root@m01 devops-shell]# awk -F: -vn=$name '$1==n' /etc/passwd
root:x:0:0:root:/root:/bin/bash

awk -vn=$name  '$1==n{print $NF}' /etc/passwd
awk -F: -vn=$name  '$1==n{print $NF}' /etc/passwd
awk -F: -vn=$name  '$1~n{print $NF}' /etc/passwd

案例38-过滤出网卡文件中ip地址那行

awk -F= '/IPADDR/{print $2}' /etc/sysconfig/network-scripts/ifcfg-eth0
10.0.0.61

2)awk的判断与循环

a)判断(了解)

如果系统根分区磁盘使用率大于80,提示磁盘空间不足

df -h|awk '$NF=="/"{ if($5>=8) print "磁盘空间不足" }'
磁盘空间不足
df -h|awk '$NF=="/"{ if($5>=8) print "磁盘空间不足" }'
awk '$NF=="/"{
  if($5>=8)
  print "磁盘空间不足"  
  }'  
 awk 'NR<=5' /etc/passwd
    awk '{if(NR<=5){print $0}}' /etc/passwd
    awk '{
           if(NR<=5){
             print $0
           }
         }' /etc/passwd
         
         
[root@m01 devops-shell]# df -h|awk -F"[ %]+" '$NF=="/"{if($(NF-1)>=5 ) print "磁盘空间不足" }'
磁盘空间不足
[root@m01 devops-shell]# df -h|awk -F"[ %]+" '$NF=="/" && $(NF-1)>=5 { print "磁盘空间不足" }'
磁盘空间不足

b) 循环(了解)

awk 'BEGIN{for(i=1;i<=100;i++) {sum=sum+i} print sum }'
awk 'BEGIN{
   for(i=1;i<=100;i++) 
      {sum=sum+i} 
   print sum  
   }'

计算任意数字的总和.

[root@m01 ~]# read -p "请输入数字空格分割:" num
请输入数字空格分割:1 2 4 5 66
[root@m01 ~]# echo $num 
1 2 4 5 66
[root@m01 devops-shell]# echo $num |awk '{for(i=1;i<=5;i++) sum=sum+$i ; print sum }'
78
[root@m01 devops-shell]# echo $num |awk '{for(i=1;i<=NF;i++) sum=sum+$i ; print sum }'
78

3)awk数组

a) 概述

  • awk数组专用于统计与分析。

    • 去重统计次数(sort+uniq)。
    • 去重求和。
  • awk数组与shell数组区别

    • awk数组: 关联数组,下标啥都行。
    • shell数组:普通数组,下标数字,shell中也有关联数组。

b) 使用

创建

awk 'BEGIN{ array[0]="lidao996";array["lidao"]=996;array[110]="sos" }'

取值

[root@oldboy-devops-shell ~]# awk 'BEGIN{
   array[0]="lidao996";
   array["lidao"]=996;
   array[110]="sos"; 
   print array[0]           
}'
lidao996
[root@oldboy-devops-shell ~]# awk 'BEGIN{ 
   array[0]="lidao996";
   array["lidao"]=996;
   array[110]="sos"; 
   print array["lidao"] 
}'           
996

[root@m01 devops-shell]# awk 'BEGIN{ array[0]="lidao";array["boss"]="oldboy";print array[0] }'
lidao
[root@m01 devops-shell]# awk 'BEGIN{ array[0]="lidao";array["boss"]="oldboy";print array[0],array["boss"] }'
lidao oldboy
[root@m01 devops-shell]# awk 'BEGIN{ array[0]="lidao";array["boss"]="oldboy"; for( n in array  ) print n }'
boss
0
[root@m01 devops-shell]# awk 'BEGIN{ array[0]="lidao";array["boss"]="oldboy"; for( n in array  ) print n,array[n] }'
boss oldboy
0 lidao

循环(专用循环)

awk专用于数组的循环
for(n  in 数组名字)
   print n(数组下标),数组名字[n]
   
 awkfor循环 数组专用循环
变量n,获取数组下标
数组名字[下标]才是对应的值
awk 'BEGIN{ 
arr 
for (n in array) 
   print n,array[n]
}'
110 sos
0 lidao996
lidao 996

c) 案例

批量赋值

cat awk-array.txt
img.oldboylinux.cn 6
bbs.oldboylinux.cn 7
avi.oldboylinux.cn 99
mp4.oldboylinux.cn 88
要求:
1.创建以url为下标,元素值是次数数组。输出数组内容。
[root@m01 devops-shell]# cat /server/files/awk_array.txt
img.oldboylinux.cn 6
bbs.oldboylinux.cn 7
avi.oldboylinux.cn 99
mp4.oldboylinux.cn 88
[root@m01 devops-shell]# awk '{ array[$1]=$2 }END{ for( n in array )print n,array[n] }' /server/files/awk_array.txt
img.oldboylinux.cn 6
avi.oldboylinux.cn 99
bbs.oldboylinux.cn 7
mp4.oldboylinux.cn 88
[root@m01 devops-shell]# awk '{ array[$1]=$2 }END{ for( n in array )print n,array[n] }' /server/files/awk_array.txt|sort -rnk2
avi.oldboylinux.cn 99
mp4.oldboylinux.cn 88
bbs.oldboylinux.cn 7
img.oldboylinux.cn 6

案例39-去重统计次数

分析文件中每个域名出现的次数
cat /server/files/url.txt
http://www.etiantian.org/index.html
http://www.etiantian.org/1.html
http://post.etiantian.org/index.html
http://mp3.etiantian.org/index.html
http://www.etiantian.org/3.html
http://post.etiantian.org/2.html

[root@m01 devops-shell]# awk -F"[/.]+" '{ array[$2]=array[$2]+1 }END{ for( n in array )print n,array[n] }' /server/files/url.txt
www 3
mp3 1
post 2
[root@m01 devops-shell]# awk -F"[/.]+" '{ array[$2]++ }END{ for( n in array )print n,array[n] }' /server/files/url.txt
www 3
mp3 1
post 2

在这里插入图片描述

统计ip地址访问次数。
awk '{url[$1]Վҡ}END{ for(name in url )print name,url[name]}' access.log |sort -rnk2 |head

案例40-统计access.log中每个ip地址的流量总数。
第1列是ip地址
第10列是流量(单位是字节)

[root@m01 devops-shell]# awk '{ array[$1]=array[$1]+$10 }END{ for( n in array )print n,array[n] }' /server/files/access.log |sort -rnk2|head
157.55.39.187 1254922
117.63.25.97 446568
47.103.21.203 179675
47.103.14.133 173519
106.14.11.104 171321
207.46.13.186 156643
207.46.13.90 104867
61.147.15.67 95592
157.55.39.4 89426
83.97.20.34 85840
[root@m01 devops-shell]# awk '{ array[$9]=array[$9]+$10 }END{ for( n in array )print n,array[n] }' /server/files/access.log |sort -rnk2|head
200 2805703
302 588708
404 106083
400 7494
301 75
Vezir.04 0
SP1 0
499 0
150 0
"-" 0

本质:ip地址是一样的然后把第10列相加。
本质: 最后输出结果
# i=i+1 == i++
# sum=sum+xxx

# array[$1]=array[$1]+1 == array[$1]++
# array[$1]=array[$1]+$10

awk与shell语法格式对比

具体语法awkshell编程
if单分支判断if (条件)
{命令
多个命令}
if 条件;then
命令
fi
if双分支判断if (条件)
{命令}
else
{命令}
if 条件;then
命令

else
命令
fi
for循环:c语言形式for(i=1;i<=10;i++)
{命令}
for(i=1;i<=10;i++)
do
{命令}
done
for循环:通用awk专用于数组的循环
for( n in 数组名字)
print n(数组下标),数组名字[n]
for n in 清单
do
{命令}
done

17. 总结

  • shell编程环境
  • shell执行方式sh/bash
  • 变量取值,赋值,命名.
  • 普通变量${} ,环境变量(了解)
  • 案例-登录系统后输出基本信息。
  • 特殊变量 $n, 0 , 0, 0,#,$?
  • 其他特殊变量:能够认识,知晓含义即可.
  • 今日案例:多种命令,多种传参方式实现计算器
  • 10
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值