【运维必会】shell脚本语言入门(二)!

  发布时间:2025-11-04 04:07:48   作者:玩站小弟   我要评论
由于内容篇幅过长,这篇文章接上一篇:【运维必会】shell脚本语言入门!老男孩SRE工程师培训,继续跟着小编来学习吧!流程控制语句| if判断语法格式:单分支:一个条件一个结果if [ 条件表达式 ]。

  由于内容篇幅过长,运维言入这篇文章接上一篇:【运维必会】shell脚本语言入门!老男孩SRE工程师培训,必会本语继续跟着小编来学习吧!

  流程控制语句

  | if判断

  语法格式:

  单分支:一个条件一个结果

  if [ 条件表达式 ];then

  命令的运维言入集合

  fi

  if [ 条件表达式 ]

  then

  命令的集合

  fi

  双分支结构:一个条件 两个结果

  if [ 条件表达式 ]

  then

  执行的命令

  else

  否则执行什么命令

  fi

  多分支:多个条件 多个结果

  if [ 条件表达式 ];then

  成立执行的命令

  elif [ 条件表达式 ];then

  成立执行的命令

  elif [ 条件表达式 ];then

  成立执行的命令

  else

  以上条件都没匹配到 执行的命令

  fi

  案例1:根据不同的操作系统版本 安装不同的YUM源

  ①如何查看操作系统的版本cat /etc/redhat-release

  ②使用if多分支进行判断

  ③执行不同的命令

  ④测试

  先写脚本的框架

#!/bin/sh #更新前进行备份 backup_yum=mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup os_version=`cat /etc/redhat-release |awk {print $(NF-1)}` if [ ${os_version%%.*} -eq 7 ];then $backup_yum wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo elif [ ${os_version%%.*} -eq 6 ];then $backup_yum wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-6.repo elif [ ${os_version%%.*} -eq 8 ];then $backup_yum wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-8.repo fi

  完善脚本

#!/bin/sh [ -f /etc/init.d/functions ] && . /etc/init.d/functions #更新前进行备份 backup_yum=mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup os_version=`cat /etc/redhat-release |awk {print $(NF-1)}` #判断网络是否正常 ping -c1 -W1 developer.aliyun.com &>/dev/null if [ $? -ne 0 ];then echo "网络不正常正在重启网卡请稍等...." systemctl restart network ping -c1 -W1 developer.aliyun.com &>/dev/null [ $? -ne 0 ] && echo "请管理员检查网络 sendmail....." fi #判断wget是否安装 which wget &>/dev/null if [ $? -ne 0 ];then echo "正在安装wget 请稍等....." yum -y install wget &>/dev/null [ $? -eq 0 ] && echo "wget 安装成功将继续更新YUM源....." fi #根据不同的操作系统版本安装不同的YUM源 if [ ${os_version%%.*} -eq 7 ];then $backup_yum echo "正在更新YUM仓库请稍后......." wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo &>/dev/null if [ $? -eq 0 ];then action "成功更新阿里云YUM仓库" /bin/true else action "更新失败请检查网络" /bin/false fi elif [ ${os_version%%.*} -eq 6 ];then $backup_yum wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-6.repo elif [ ${os_version%%.*} -eq 8 ];then $backup_yum wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-8.repo fi

  案例2:使用if判断比较两个的数字大小

#!/bin/sh # 判断num1数字如果是不是纯数字 或者num2不是纯数字 表达式都成立 read -p "请输入两个数字: " num1 num2 if [[ ! $num1 =~ ^[0-9]+$ || ! $num2 =~ ^[0-9]+$ ]];then echo "请输入整数" exit fi # 比较两数大小 if [ $num1 -gt $num2 ];then echo "$num1>$num2" elif [ $num1 -lt $num2 ];then echo "$num1<$num2" else echo "$num1=$num2" fi

  案例3:安装不同的PHP版本

  菜单的使用方法

方法一: # cat menu.sh #!/bin/sh echo -e "\t\t\t1.PHP5.4" echo -e "\t\t\t2.PHP5.5" echo -e "\t\t\t3.PHP7.1" echo -e "\t\t\t4.PHP7.3" 方法二: cat<<EOF 1.PHP5.4 2.PHP5.5 3.PHP7.1 4.PHP7.3 EOF

  PHP安装脚本

#!/bin/sh cat<<EOF 1.PHP5.4 2.PHP5.5 3.PHP7.1 4.PHP7.3 EOF read -p "请选择要安装的版本的编号或者是PHP版本号:[1|PHP5.4] " num if [ $num = 1 -o $num = "PHP5.4" ];then echo "yum -y install PHP5.4........" elif [ $num = 2 -o $num = "PHP5.5" ];then echo "yum -y install PHP5.5........" elif [ $num = 4 -o $num = "PHP7.3" ];then echo "yum -y install PHP7.3........" fi

  | for循环

  语法格式:

  for 变量 in 值的列表 值: 数字 字符串 命令 序列 默认以空格来分隔

  do

  执行的动作 命令的集合

  done

  输出结果可以和变量相关 也可以不相关

和变量相关: # cat for.sh #!/bin/sh for num in 1 2 3 do echo $num done 和变量不相关: # cat for.sh #!/bin/sh for num in 1 2 3 do echo hehe done 统计for循环总共循环了多少次: # cat for.sh #!/bin/sh for num in {1..1000} do let i++ done echo $i

  for循环 值为命令

  输出结果可以和变量相关 也可以不相关

# cat for.sh #!/bin/sh for num in `cat /etc/hosts` do echo $num done

  for循环案例:

  ping 一个c的地址 通表示在线 不通表示离线 10.0.0.1-10.0.0.254

# cat for.sh #!/bin/sh for i in {1..254} do ping -c 1 10.0.0.${i} &>/dev/null [ $? -eq 0 ] && echo "10.0.0.${i} 服务器在线" || echo "10.0.0.${i} 服务器不在线" done

  for循环案例: 批量创建用户

#!/bin/sh read -p "请输入要创建用户的个数: " num read -p "请输入要创建用户的前缀: " prefix for i in `seq $num` do user=${prefix}$i id $user &>/dev/null if [ $? -ne 0 ];then useradd $user &>/dev/null [ $? -eq 0 ] && echo "$user 用户创建成功" else echo "useradd: user $user already exists" fi done

  for循环添加和删除用户 不带密版

#!/bin/sh read -p "请输入用户的企商汇个数: " num read -p "请输入用户的前缀: " prefix echo "当前输入的用户名为:" for i in `seq $num` do echo "${prefix}$i" done read -p "请问您是要删除以上用户还是创建以上用户[del|add]: " re if [ $re = add ];then for i in `seq $num` do user=${prefix}$i id $user &>/dev/null if [ $? -ne 0 ];then useradd $user &>/dev/null [ $? -eq 0 ] && echo "$user 用户创建成功" else echo "useradd: user $user already exists" fi done elif [ $re = del ];then for i in `seq $num` do user=${prefix}$i id $user &>/dev/null if [ $? -eq 0 ];then userdel -r $user &>/dev/null [ $? -eq 0 ] && echo "$user 用户删除成功" else echo "用户不存在" fi done fi

  | while循环

  语法结构:

  while [ 条件表达式 ] 条件表达式成立(为真)则执行 否则不执行

  do

  命令

  done

  使用实例:死循环

方式一: #!/bin/sh while true do echo hehe sleep 1 done 方式二: #!/bin/sh while [ 10 -gt 5 ] do echo hehe sleep 1 done 方式三: #!/bin/sh while [ -f /etc/hosts ] do echo hehe sleep 1 done

  while读取文件 取值语法结构:

  while read line # line变量名称 自定义

  do

  执行的命令

  done

  使用实例:

方式一: #!/bin/sh while read line do echo $line done</etc/hosts 方式二: #!/bin/sh while read line do user=`echo $line|awk {print $1}` useradd $user pass=`echo $line|awk {print $2}` echo $pass|passwd --stdin $user done<user.txt

  流程控制语句

  使用实例:

控制语句exit: #!/bin/sh while true do echo test....... exit echo oldboy....... done echo hehe........... 控制语句break: #!/bin/sh while true do echo test....... break echo oldboy....... done echo hehe........... 控制语句continue: #!/bin/sh while true do echo test....... continue echo oldboy....... done echo hehe...........

  流程控制语句案例:

  exit 创建完oldboy5用户 退出当前脚本 只能创建5个用户

#!/bin/sh for i in `seq 5` do user=oldboy$i id $user &>/dev/null if [ $? -eq 0 ];then exit else useradd $user &>/dev/null [ $? -eq 0 ] && echo "$user 创建成功" fi done

  break创建完oldboy5用户 跳出本层循环继续往下执行 创建5个用户

#!/bin/sh for i in `seq 5` do user=oldboy$i id $user &>/dev/null if [ $? -eq 0 ];then break else useradd $user &>/dev/null [ $? -eq 0 ] && echo "$user 创建成功" fi done echo oldboy

  continue在oldboy1到oldboy5用户已经存在情况下继续向下创建用户

#!/bin/sh for i in `seq 10` do user=oldboy$i id $user &>/dev/null if [ $? -eq 0 ];then continue else useradd $user &>/dev/null [ $? -eq 0 ] && echo "$user 创建成功" fi done echo hehe...................

  break等级跳,break只会跳出当前层循环

#!/bin/sh while true do 必会本语 echo "第一层" while true do echo 第二层 sleep 1 while true do echo 第三层 sleep 1 break 3 echo oldboy....... done done done echo hehe...........

  shell函数

  1、函数是运维言入命令的集合 完成特定功能的代码块

  2、函数代码块 方便复用

  3、必会本语函数类似变量 只有先定义才能执行

  区别:变量不调用也会执行 name=oldboy 函数只有调用才会执行代码

  | 函数的运维言入定义

#!/bin/sh fun1(){ echo "函数的第一种定义方式" } fun1 function fun2 { echo "函数的第二种定义方式" } fun2 function fun3(){ echo "函数的第三种定义方式" } fun3

  案例: 菜单

#!/bin/sh fun1(){ echo -e "\t\t\t\t1.包子" echo -e "\t\t\t\t2.麻辣烫" echo -e "\t\t\t\t3.小米粥" echo -e "\t\t\t\t4.汉堡" echo -e "\t\t\t\t5.烧烤" } fun1

  | 函数复用

# cat 1.sh #!/bin/bash . /server/scripts/day4/test.sh fun3 # sh 1.sh 函数的第三种定义方式 # cat test.sh #!/bin/sh fun1(){ echo "函数的第一种定义方式" } function fun2 { echo "函数的第二种定义方式" } function fun3(){ echo "函数的第三种定义方式" }

  案例: 函数的传参

  函数调用在函数名称的后面

  fun1 参数1 参数2 参数3 对应函数中的 $1 $2 $3

  函数判断文件是否存在

# cat fun.sh #!/bin/sh fun1(){ if [ -f $1 ];then echo "$1 文件存在" else echo "$1 文件不存在" fi } fun1 /etc/hosts # sh fun.sh /etc/hosts 文件存在 # cat fun.sh #!/bin/sh fun1(){ if [ -f $3 ];then echo "$3 文件存在" else echo "$3 文件不存在" fi } fun1 /etc/hosts /etc/passwd /etc/fsttttttt # sh fun.sh /etc/fsttttttt 文件不存在 # cat fun.sh #!/bin/sh fun1(){ if [ -f $1 ];then echo "$1 文件存在" else echo "$1 文件不存在" fi } fun1 $2 # sh fun.sh /etc/passwd /etc/hosts /etc/hosts 文件存在

  函数可以识别变量

#!/bin/sh file=$1 fun1(){ if [ -f $file ];then echo "$file 文件存在" else echo "$file 文件不存在" fi } fun1 # sh fun.sh /etc/hosts /etc/hosts 文件存在

  | 函数变量

  可以识别全局变量 函数外的都是当前shell的全局变量

  只在函数内生效的变量定义

# cat fun.sh #!/bin/sh fun1(){ local num=20 for i in `seq $num` do total=$[$count+$i] done echo "当前运算的结果是: $total" } fun1 echo $num # sh fun.sh 当前运算的结果是: 20

  函数的云南idc服务商返回值 return

# cat fun.sh #!/bin/sh fun1(){ echo 100 return 50 } result=`fun1` echo "当前函数的返回值是: " $? echo "当前函数的执行结果: " $result # sh fun.sh 当前函数的返回值是: 50 当前函数的执行结果: 100

  利用返回值来判断

  错误写法

错误写法一: #!/bin/sh fun1(){ if [ -f $1 ];then return 50 else return 100 fi } fun1 $1 [ $? -eq 50 ] && echo "文件存在" [ $? -eq 100 ] && echo "文件不存在" 错误写法二: #!/bin/sh fun1(){ if [ -f $1 ];then return 50 else return 100 fi } fun1 $1 if [ $? -eq 50 ];then echo 文件存在 elif [ $? -eq 100 ];then echo 文件不存在 fi

  解决方法:

[ $? -eq 50 ] && echo 文件存在 || echo 文件不存在 if [ $? -eq 50 ];then echo 文件存在 else echo 文件不存在 fi 赋值的方式 re=$? if [ $re -eq 50 ];then echo 文件存在 elif [ $re -eq 100 ];then echo 文件不存在 fi

  case语句

  语法结构:

  case 变量 in 变量 直接传参 赋值传参

  匹配模式1)

  执行的命令集合

  ;;

  匹配模式2)

  执行命令集合

  ;;

  匹配模式3)

  执行命令集合

  ;;

  *)

  无匹配后序列 执行命令集合

  esac

  案例

# cat case.sh #!/bin/sh case $1 in Shell) echo shell...... ;; MySQL) echo MySQL...... ;; Docker) echo docker...... ;; *) echo hehe...... esac # sh case.sh Shell shell...... # sh case.sh MySQL MySQL...... # sh case.sh Docker docker......

  或者的使用

# cat case.sh #!/bin/sh case $1 in Shell|1) echo shell...... ;; MySQL|2) echo MySQL...... ;; Docker|hehe) echo docker...... ;; *) # 匹配不到可以给用户执行提示 echo "Usage: $0 [Shell|MySQL|Docker]" esac # sh case.sh 1 shell..... # sh case.sh hehe docker...... # sh case.sh Shell shell......

  案例: 使用case写一个菜单 显示系统的登录 负载 磁盘 内存等信息

  1、先写菜单:f查看内存、必会本语w查看负载、运维言入d查看磁盘、必会本语l查看登录信息、运维言入m显示菜单

  2、必会本语让用户输入查看的运维言入信息read -p 请输入查看的信息的编号:

  3、使用case做判断 执行对应的必会本语命令

#!/bin/sh menu(){ cat<<EOF 1.f查看内存 2.w查看负载 3.d查看磁盘 4.l查看登录信息 5.m显示菜单 6.e退出 EOF } menu while true do read -p "请输入你想查看的信息的编号或者字母:[1|f|2|w] " num case $num in 1|f) clear free -h ;; 2|w) clear uptime ;; 3|d) clear df -h ;; 5|m) clear menu ;; 6|e) exit ;; *) echo "Usage: $0 [1|f|2|w]" esac done

  case案例:Nginx启动脚本

  Nginx启动两种方式:1种是systemctl管理启动、1种是运维言入命令行直接启动以上两种同时只能使用一种启动

  命令行的方式

  /usr/sbin/nginx启动

  /usr/sbin/nginx -s stop 停止

  重启不支持 先停止在启动

  /usr/sbin/nginx -s reload查看状态 过滤端口或者PID

#!/bin/sh [ -f /etc/init.d/functions ] && . /etc/init.d/functions nginx=/usr/sbin/nginx Te(){ if [ $? -eq 0 ];then action "Nginx $1 is" /bin/true else action "Nginx $1 is" /bin/false fi } case $1 in start) $nginx Te $1 ;; stop) $nginx -s stop Te $1 ;; restart) $nginx -s stop sleep 1 $nginx Te $1 ;; reload) $nginx -s reload Te $1 ;; status) Port=`netstat -tnulp|grep nginx|grep master|grep \btcp\b|awk {print $4}` echo "Nginx_Port: $Port" PID=`ps axu|grep nginx|grep master|awk {print $2}` echo "Nginx_PID: $PID" ;; *) echo "Usage $0 [start|stop|restart|reload|status]" esac

  case案例: jumpserver 跳板机

  1、菜单显示我们可以登录的服务信息:web01 10.0.0.7、web02 10.0.0.8

  2、选择登录的服务器

  3、源码下载使用case匹配

#!/bin/sh web01=10.0.0.7 web02=10.0.0.8 MySQL=10.0.0.51 BACKUP=10.0.0.41 NFS=10.0.0.31 menu(){ cat<<EOF 1.web01 10.0.0.7 2.web02 10.0.0.8 3.MySQL 10.0.0.51 4.BACKUP 10.0.0.41 5.NFS 10.0.0.31 6.menu 显示菜单 7.exit 退出 EOF } menu trap "" HUP INT TSTP while true do read -p "请输入你要登录服务器的编号或者主机名称:[1|web01|6显示菜单] " num case $num in 1|web01) ssh root@$web01 ;; 2|web02) ssh root@$web02 ;; 3|MySQL) ssh root@$MySQL ;; 4|BACKUP) ssh root@$BACKUP ;; 5|NFS) ssh root@$NFS ;; 6|menu) menu ;; 7|exit) exit ;; *) echo "Usage $0 [1|web01|2|web02]" esac done

  case案例: jumpserver 跳板机扩展

  1、运维开发权限不同:运维:all权限 所有服务器都可以连接 、开发:只能连接web1 web2

  2、设置密码 只能失败三次

  3、2级菜单 服务器信息

#!/bin/sh web01=10.0.0.7 web02=10.0.0.8 MySQL=10.0.0.51 BACKUP=10.0.0.41 NFS=10.0.0.31 users(){ cat<<EFO 1.运维 2.开发 3.退出 EFO } users ops(){ cat<<EOF 1.web01 10.0.0.7 2.web02 10.0.0.8 3.MySQL 10.0.0.51 4.BACKUP 10.0.0.41 5.NFS 10.0.0.31 6.menu 显示菜单 7.exit 退出 EOF } dev(){ cat<<EOF 1.web01 10.0.0.7 2.web02 10.0.0.8 3.menu 显示菜单 4.exit 退出 EOF } trap "echo 别瞎按小心爆炸" HUP INT TSTP read -p "请输入你的身份: " au if [ $au = 1 ];then >/tmp/yunwei.pwd while true do yunwei=`cat /tmp/yunwei.pwd | wc -l` if [ $yunwei -lt 3 ];then read -s -p "请输入运维的密码: " pass if [ $pass = woshiyunwei ];then echo "登录成功欢迎牛逼的运维!!!" break else echo "密码不正确请重新输入密码" echo 1 >> /tmp/yunwei.pwd continue fi else echo "密码错误次数太多,现已退出" exit fi done ops while true do read -p "请输入你要登录服务器的编号或者主机名称:[1|web01|6显示菜单] " num case $num in 1|web01) ssh root@$web01 ;; 2|web02) ssh root@$web02 ;; 3|MySQL) ssh root@$MySQL ;; 4|BACKUP) ssh root@$BACKUP ;; 5|NFS) ssh root@$NFS ;; 6|ops) ops ;; 7|exit) exit ;; *) echo "Usage $0 [1|web01|2|web02]" esac done elif [ $au = 2 ];then >/tmp/kaifa.pwd while true do kaifa=`cat /tmp/kaifa.pwd | wc -l` if [ $kaifa -lt 3 ];then read -s -p "请输入开发的密码: " pass if [ $pass = woshikaifa ];then echo "登录成功欢迎小小的开发!!!" break else echo "密码不正确请重新输入密码" echo 1 >>/tmp/kaifa.pwd continue fi else echo "密码错误次数太多,现已退出" exit fi done dev while true do read -p "请输入你要登录服务器的编号或者主机名称:[1|web01|3显示菜单] " num case $num in 1|web01) ssh root@$web01 ;; 2|web02) ssh root@$web02 ;; 3|dev) dev ;; 4|exit) exit ;; *) echo "Usage $0 [1|web01|2|web02]" esac done elif [ $au = 3 ];then exit fi

  shell变量数组

  数组的分类

  普通数组:只能用数字作为索引

  关联数组:数字或者字符串作为索引

  数组的结构

  类似变量:一个名称对应一个值,一个筐子里面只装了一个水果(苹果)

  数组:一个名词对应多个值,一个筐子里面装了很多盒子,每个盒子里有不同的水果

  索引:盒子的名称,称为索引也称为下标也称为元素名称

  数组的格式

  数组名称[索引名称]=元素的值筐子[盒子1]=苹果筐子[盒子2]=梨筐子[盒子3]=黄瓜

  普通数组的盒子(索引)从0开始筐子[0]=值

  | 普通数组的定义方式

  第一种定义方式:按照索引进行定义

array[1]=shell array[2]=mysql array[3]=docker

  查看数组:按照索引进行查看

# echo ${array[2]} mysql # echo ${array[1]} shell # echo ${array[3]} docker

  查看数组中所有的值

# echo ${array[*]} shell mysql docker # echo ${array[@]} shell mysql docker

  查看数组中所有的索引(下标) 所有的盒子的名称

# echo ${!array[@]} 1 2 3

  查看索引的总个数

# echo ${#array[@]}3

  查看系统的普通数组

declare -a

  第二种定义方式:使用默认的索引来定义

# array=(shell mysql docker oldboy)# echo ${array[*]}shell mysql docker oldboy# echo ${!array[*]}0 1 2 3

  第三种定义方式:使用自定义索引和默认索引定义

# array=([5]=shell mysql [10]=docker hehe)# echo ${array[*]}shell mysql docker hehe# echo ${!array[*]}5 6 10 11

  第四种定义方式:

# array=(`cat /etc/passwd|awk -F: {print $1}`)# echo ${array[*]}root bin daemon adm lp sync shutdown halt mail operator games ftp nobody systemd-network dbus polkitd tss abrt sshd postfix test1 test2 test3 test4 test5 zhangsan lisi erdan goudan gousheng baoyi oldboy5 oldboy1 oldboy2 oldboy3 oldboy4 oldboy6 oldboy7 oldboy8 oldboy9 oldboy10 nginx# echo ${!array[*]}0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41

  | 数组的遍历

# unset array# array=(10 20 30 40)# echo ${array[*]}10 20 30 40# for i in ${array[*]};do echo $i;done10203040

  案例

# array=(10.0.0.1 10.0.0.7 10.0.0.254 www.baidu.com)# for i in ${array[*]};do ping -c1 -W1 $i;done# cat array.sh#!/bin/ship=(10.0.0.1www.baidu.com10.0.0.710.0.0.8www.sinaaaa.com10.0.0.254www.weibo.com)for i in ${ip[*]}do ping -c1 -W1 $i &>/dev/null if [ $? -eq 0 ];then echo "$i 在线" else echo "$i 不在线" fidone

  使用索引的方式进行遍历

# echo ${array[*]}10.0.0.1 10.0.0.7# echo ${!array[*]}0 1# echo ${array[0]}10.0.0.1# echo ${array[1]}10.0.0.7# for i in ${!array[*]};do echo ${array[$i]};done10.0.0.110.0.0.7

  | 关联数组

  使用字符串作为索引,定义方式:

  默认的定义方式是普通数组

# array[index1]=shell# array[index2]=mysql# array[index3]=docker# echo ${array[*]}docker# declare -a |grep arraydeclare -a array=([0]="docker")

  配置关联数组 提前声明 declare -A 声明关联数组

# declare -A array# array[index1]=shell# array[index2]=mysql# array[index3]=redis# echo ${array[*]}shell mysql redis

  查看索引

echo ${!array[*]}

  案例:统计当前的男性和女性出现的次数

# cat sex.txtmmfmfx# for i in `cat sex.txt`;do let $i++;done# echo $m3# echo $f2# echo $x1

  执行过程

#!/bin/shdeclare -A sexwhile read linedo let sex[$line]++ line=m let sex[m]++ line=x let sex[x]++ line=f let sex[f]++done<sex.txt

  直接查看

#!/bin/shdeclare -A sexwhile read linedo let sex[$line]++done<sex.txtecho m 出现了 ${sex[m]} 次echo f 出现了 ${sex[f]} 次echo x 出现了 ${sex[x]} 次

  数组遍历

#!/bin/shdeclare -A sexwhile read linedo let sex[$line]++done<sex.txtfor i in ${!sex[*]}do echo $i 出现了 ${sex[$i]} 次done

  案例: 统计nginx日志每个IP出现的次数

#!/bin/shdeclare -A ipwhile read linedo let ip[`echo $line|awk {print $1}`]++done</var/log/nginx/access.logfor i in ${!ip[*]}do echo $i 出现了 ${ip[$i]} 次done
  • Tag:

相关文章

最新评论