The use of arrays in shell scripts
本篇内容介绍了"shell脚本中数组的用法"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
问题描述:某个员工的linux系统有大量重复的软件(版本不同),导致使用yum安装软件时报错。现在需要将重复的软件找出来,将低版本的软件删掉。执行rpm -qa | sort 显示如下:
[root@cws85 ~]# rpm -qa | sort a52dec-0.7.4-27.el7.x86_64aalib-libs-1.4.0-0.22.rc5.el7.x86_64abattis-cantarell-fonts-0.0.25-1.el7.noarchabrt-2.1.11-52.el7.centos.x86_64abrt-addon-ccpp-2.1.11-52.el7.centos.x86_64abrt-addon-kerneloops-2.1.11-52.el7.centos.x86_64abrt-addon-pstoreoops-2.1.11-52.el7.centos.x86_64abrt-addon-python-2.1.11-52.el7.centos.x86_64abrt-addon-vmcore-2.1.11-52.el7.centos.x86_64abrt-addon-xorg-2.1.11-52.el7.centos.x86_64abrt-cli-2.1.11-52.el7.centos.x86_64abrt-console-notification-2.1.11-52.el7.centos.x86_64abrt-dbus-2.1.11-52.el7.centos.x86_64abrt-desktop-2.1.11-52.el7.centos.x86_64abrt-gui-2.1.11-52.el7.centos.x86_64abrt-gui-libs-2.1.11-52.el7.centos.x86_64abrt-java-connector-1.0.6-12.el7.x86_64abrt-libs-2.1.11-52.el7.centos.x86_64abrt-python-2.1.11-52.el7.centos.x86_64abrt-retrace-client-2.1.11-52.el7.centos.x86_64abrt-tui-2.1.11-52.el7.centos.x86_64accountsservice-0.6.50-4.el7.1.x86_64accountsservice-libs-0.6.50-4.el7.1.x86_64acl-2.2.51-14.el7.x86_64adcli-0.8.1-6.el7_6.1.x86_64adwaita-cursor-theme-3.28.0-1.el7.noarchadwaita-gtk2-theme-3.28-2.el7.x86_64adwaita-icon-theme-3.28.0-1.el7.noarchadwaita-qt5-1.0-1.el7.x86_64aic94xx-firmware-30-6.el7.noarchalsa-firmware-1.0.28-2.el7.noarchalsa-lib-1.1.6-2.el7.x86_64alsa-plugins-pulseaudio-1.1.6-1.el7.x86_64alsa-tools-firmware-1.1.0-1.el7.x86_64alsa-utils-1.1.6-1.el7.x86_64anaconda-core-21.48.22.121-1.el7.centos.x86_64anaconda-core-21.48.22.147-1.el7.centos.0.1.x86_64anaconda-gui-21.48.22.147-1.el7.centos.0.1.x86_64anaconda-tui-21.48.22.121-1.el7.centos.x86_64 #这是重复软件的低版本anaconda-tui-21.48.22.147-1.el7.centos.x86_64 #这是重复软件的高版本anaconda-widgets-21.48.22.147-1.el7.centos.0.1.x86_64..........省略总共2586个软件
要求:如上所示,需要将低版本的软件删除,如下是例外:
[root@cws85 ~]# rpm -qa | grep audit-libs-[0-9]
audit-libs-2.8.4-4.el7.i686
audit-libs-2.8.4-4.el7.x86_64
虽然是重复软件,但一个是x86_64,一个是i686,这样不能删除,只能删除重复的_x86_64结尾的软件
数组:脚本中用到了数组,下面是数组的部分内容概述:
1.数组定义:
declare -a 数组名 #定义索引数组,下标从0开始
declare -A 数组名 #定义关联数组,下标为任意字符
2.数组赋值与复制:
2.1.可以通过命令替换的方式给数组赋值: declare -a SOFT1=($(rpm -qa | sort)) #数组SOFT1保存着所有软件
2.2.数组复制操作:linux2=(${linux1[@]}) #数组linux2复制了数组linux1的内容
3.数组的字符串操作:
3.1.字符串的操作符可以用在数组上,如:${#string} 用于数组 ${#array[@]},等等等等。
3.2.数组遍历: for i in ${!SOFT[@]} #注意加上感叹号可以遍历数组中的值,假设SOFT的下标最大是2586,通过for循环可以遍历完数组,i的值从0依次到2586。
脚本内容:
#!/bin/bashdeclare -a SOFT1=($(rpm -qa | sort)) #数组SOFT1保存所有软件名称for i in ${!SOFT1[*]} #遍历数组SOFT1 do declare -a SOFT2[$i]=${SOFT1[$i]%%-[0-9]*} #数组SOFT2复制数组SOFT1的部分内容,%%是字符串截取符号,相当于去掉软件的版本号,只保留软件名称 donefor i in $(seq 0 $((${#SOFT2[@]}-1))) #遍历数组SOFT2 do let "j=$i+5" for (( ;i>/tmp/soft && continue #小于2输出该软件没有重复的版本 elif (( "${#SOFT3[@]}" > 2 )) #如果下标大于2,也就是(rpm -qa | grep 重复软件)有多于2个软件 then X86=0 I686=0 #初始化两个变量,用于后面比较 for i in ${!SOFT3[*]} #遍历数组SOFT3 do [[ "${SOFT3[$i]##*.}" == "i686" ]] && I686=$((I686+1)) || X86=$((X86+1)) #如果软件名结尾是i686,那么变量I686加1,否则X86加1 done (( "$X86" >= "$I686" )) && echo "${SOFT3[0]} can1 delete" >>/tmp/soft #如果X86值大于I686,输出软件能够删除 elif (( "${#SOFT3[@]}" == 2 )) #如果下标等于2,也就是(rpm -qa | grep 重复软件)有两个 then [[ "${SOFT3[0]##*.}" == "i686" || "${SOFT3[1]##*.}" == "i686" ]] && { echo "${SOFT3[0]} only two packages but has I686" >>/tmp/soft ; continue ; } #两个软件里只要有1个是i686结尾的,输出不能删除 echo "${SOFT3[0]} can2 delete" >>/tmp/soft fi fi done done
脚本说明:
1.数组SOFT1保存所有软件的完整名称,数组SOFT2是通过数组复制加上字符串的替换,截取出不带版本名称的软件名,比如 SOFT1[4]=abrt-addon-ccpp-2.1.11-52.el7.centos.x86_64, SOFT2[4]=abrt-addon-ccpp。
2.利用for循环遍历数组SOFT2来检测那些是重复软件,如下:
for i in $(seq 0 $((${#SOFT2[@]}-1))) #遍历数组SOFT2do let "j=$i+5" #j比i大5,用于测试某个软件名与它后面的5个软件名是否相等,因为是通过rpm -qa | sort排序过,所以软件名都是按照字母顺序排的,比较5个就可以了。 for (( ;i