shell script practice - Array

Problem description : an employee of a large number of duplicate linux system software (different versions), resulting in an error when using yum to install the software. Now repeat the software you need to find out, the low version of the software will be deleted. Execute rpm -qa | sort shown below:

[root@cws85 ~]# rpm -qa | sort 
a52dec-0.7.4-27.el7.x86_64
aalib-libs-1.4.0-0.22.rc5.el7.x86_64
abattis-cantarell-fonts-0.0.25-1.el7.noarch
abrt-2.1.11-52.el7.centos.x86_64
abrt-addon-ccpp-2.1.11-52.el7.centos.x86_64
abrt-addon-kerneloops-2.1.11-52.el7.centos.x86_64
abrt-addon-pstoreoops-2.1.11-52.el7.centos.x86_64
abrt-addon-python-2.1.11-52.el7.centos.x86_64
abrt-addon-vmcore-2.1.11-52.el7.centos.x86_64
abrt-addon-xorg-2.1.11-52.el7.centos.x86_64
abrt-cli-2.1.11-52.el7.centos.x86_64
abrt-console-notification-2.1.11-52.el7.centos.x86_64
abrt-dbus-2.1.11-52.el7.centos.x86_64
abrt-desktop-2.1.11-52.el7.centos.x86_64
abrt-gui-2.1.11-52.el7.centos.x86_64
abrt-gui-libs-2.1.11-52.el7.centos.x86_64
abrt-java-connector-1.0.6-12.el7.x86_64
abrt-libs-2.1.11-52.el7.centos.x86_64
abrt-python-2.1.11-52.el7.centos.x86_64
abrt-retrace-client-2.1.11-52.el7.centos.x86_64
abrt-tui-2.1.11-52.el7.centos.x86_64
accountsservice-0.6.50-4.el7.1.x86_64
accountsservice-libs-0.6.50-4.el7.1.x86_64
acl-2.2.51-14.el7.x86_64
adcli-0.8.1-6.el7_6.1.x86_64
adwaita-cursor-theme-3.28.0-1.el7.noarch
adwaita-gtk2-theme-3.28-2.el7.x86_64
adwaita-icon-theme-3.28.0-1.el7.noarch
adwaita-qt5-1.0-1.el7.x86_64
aic94xx-firmware-30-6.el7.noarch
alsa-firmware-1.0.28-2.el7.noarch
alsa-lib-1.1.6-2.el7.x86_64
alsa-plugins-pulseaudio-1.1.6-1.el7.x86_64
alsa-tools-firmware-1.1.0-1.el7.x86_64
alsa-utils-1.1.6-1.el7.x86_64
anaconda-core-21.48.22.121-1.el7.centos.x86_64
anaconda-core-21.48.22.147-1.el7.centos.0.1.x86_64
anaconda-gui-21.48.22.147-1.el7.centos.0.1.x86_64
anaconda-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个软件

Requirements : As indicated above, the low version of the software needs to be deleted, the following exception:

[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
although repeat software, but one is x86_64, one is the i686, so can not be deleted, the software can remove duplicate _x86_64 ending

Array : script used in the array, the following is part of an array of content:

1. Array definition:
DECLARE -a # define an array name indexed array index starts from 0
defined declare -A array name associative array, the subscript any character

2. array assignment and copy:
2.1 through alternative ways to command array assignment: declare -a SOFT1 = ($ ( rpm -qa | sort)) # SOFT1 array holds all the software
2.2 array copy operation: linux2 = (. $ {linux1 [@]}) # linux2 array of copying the contents of the array linux1

3. The operation of the array of strings:
3.1 the string operator can be used in an array, such as: $ {# string} array for $ {# array [@]} , and so on and so forth.
3.2 array traversal:. For i in $ # Note exclamation point values in the array can traverse the assumed maximum SOFT subscript is 2586, can be completely through the array for loop, the value of i from 0 {SOFT [@]!} turn to 2586.

Script Content :

#!/bin/bash
declare -a SOFT1=($(rpm -qa | sort))      #数组SOFT1保存所有软件名称

for i in ${!SOFT1[*]}                 #遍历数组SOFT1
 do
   declare -a SOFT2[$i]=${SOFT1[$i]%%-[0-9]*}        #数组SOFT2复制数组SOFT1的部分内容,%%是字符串截取符号,相当于去掉软件的版本号,只保留软件名称
 done

for i in $(seq 0 $((${#SOFT2[@]}-1)))        #遍历数组SOFT2
  do
     let "j=$i+5"  
     for (( ;i<j;j--))            #i小于j时跳出循环,循环执行5次
       do
         if [ "${SOFT2[$i]}" == "${SOFT2[$j]}" ]     #测试是否有重复软件
           then
              declare -a SOFT3=($(rpm -qa | grep "^${SOFT2[$i]}-[0-9]" | sort))    #如果软件有重复,执行rpm -qa | grep 重复软件名,赋值给数组SOFT3
              if (( "${#SOFT3[@]}" < 2 ))     #检测数组SOFT3的下标个数是否小于2(多加一层保险)
                then
                   echo "${SOFT2[$i]} no repeat version" >>/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

Script Description :

1. SOFT1 intact array of names of all the software, is replaced with the string array SOFT2 replication through the array, without intercepting the software version name of the name, such SOFT1 [4] = abrt-addon-ccpp-2.1.11- 52.el7.centos.x86_64, SOFT2 [4] = abrt-addon-ccpp.

2. Use for loop through the array to detect those SOFT2 software is repeated as follows:

for i in $(seq 0 $((${#SOFT2[@]}-1)))       #遍历数组SOFT2
do    
     let  "j=$i+5"       #j比i大5,用于测试某个软件名与它后面的5个软件名是否相等,因为是通过rpm -qa | sort排序过,所以软件名都是按照字母顺序排的,比较5个就可以了。  
     for (( ;i<j;j--))        
         do
             if [ "${SOFT2[$i]}" == "${SOFT2[$j]}" ]         #比较是否有重复软件名

3. If there are duplicate, to deal with the problem of software extension, only to repeat the name of the X86 software before the end of the output of the software can be deleted. Using array SOFT3 = ($ (rpm -qa | grep "^ $ {SOFT2 [$ i]} - [0-9]" | sort)) to store searched repeated software, and making comparison determination

Script output : the output is redirected to a file, the file contents are as follows:

anaconda-core-21.48.22.121-1.el7.centos.x86_64 can2 delete
anaconda-tui-21.48.22.121-1.el7.centos.x86_64 can2 delete
audit-libs-2.8.4-4.el7.i686 only two packages but has I686
avahi-libs-0.6.31-17.el7.x86_64 can2 delete
bzip2-libs-1.0.6-13.el7.i686 only two packages but has I686
copy-jdk-configs-2.2-5.el7_4.noarch can2 delete
cracklib-2.9.0-11.el7.i686 only two packages but has I686
cryptsetup-libs-1.7.4-3.el7_4.1.x86_64 can2 delete
dbus-1.10.24-13.el7_6.x86_64 can2 delete
dbus-libs-1.10.24-13.el7_6.x86_64 can2 delete
device-mapper-event-libs-1.02.149-10.el7_6.3.x86_64 can2 delete
elfutils-libelf-0.172-2.el7.i686 only two packages but has I686
elfutils-libs-0.172-2.el7.i686 only two packages but has I686
fprintd-0.5.0-4.0.el7_0.x86_64 can2 delete
freetype-2.8-12.el7_6.1.i686 only two packages but has I686
glib2-2.54.2-2.el7.x86_64 can2 delete
glibc-2.17-260.el7_6.6.i686 only two packages but has I686
........省略
总共81行,能删除的有52行(有少数错误,后面说明)

Script Debugging Information : Part of sh -x script name appears as follows:

+ SOFT1=($(rpm -qa | sort))      #数组SOFT1保存完整软件名
++ rpm -qa
++ sort
+ declare -a SOFT1
+ for i in '${!SOFT1[*]}'                #遍历数组SOFT1 
+ declare -a 'SOFT2[0]=a52dec'      #给数组SOFT2赋值,只保留软件名
+ for i in '${!SOFT1[*]}'
+ declare -a 'SOFT2[1]=aalib-libs'
+ for i in '${!SOFT1[*]}'
+ declare -a 'SOFT2[2]=abattis-cantarell-fonts'
+ for i in '${!SOFT1[*]}'
+ declare -a 'SOFT2[3]=abrt'
+ for i in '${!SOFT1[*]}'
+ declare -a 'SOFT2[4]=abrt-addon-ccpp'
+ ..............省略,总共2586个

++ seq 0 2585   
+ for i in '$(seq 0 $((${#SOFT2[@]}-1)))'          #遍历数组SOFT2,测试哪些是重复软件
+ let j=0+5       #总共比较5次
+ (( 1 ))
+ (( i<j ))
+ '[' a52dec == abrt-addon-kerneloops ']'
+ (( j-- ))
+ (( i<j ))
+ '[' a52dec == abrt-addon-ccpp ']'
+ (( j-- ))
+ (( i<j ))
+ '[' a52dec == abrt ']'
+ (( j-- ))
+ (( i<j ))
+ '[' a52dec == abattis-cantarell-fonts ']'
+ (( j-- ))
+ (( i<j ))
+ '[' a52dec == aalib-libs ']'                             #a53dec...不是一个重复软件
+ (( j-- ))
+ (( i<j ))
+ for i in '$(seq 0 $((${#SOFT2[@]}-1)))'     #比较下一个,数组下标加1
+ let j=1+5
...........................................................................省略
+ for i in '$(seq 0 $((${#SOFT2[@]}-1)))'
+ let j=35+5             #数组下标到35
+ (( 1 ))
+ (( i<j ))
+ '[' anaconda-core == anaconda-widgets ']'
+ (( j-- ))
+ (( i<j ))
+ '[' anaconda-core == anaconda-tui ']'
+ (( j-- ))
+ (( i<j ))
+ '[' anaconda-core == anaconda-tui ']'
+ (( j-- ))
+ (( i<j ))
+ '[' anaconda-core == anaconda-gui ']'
+ (( j-- ))
+ (( i<j ))
+ '[' anaconda-core == anaconda-core ']'                                 #这里找到重复软件
+ SOFT3=($(rpm -qa | grep "^${SOFT2[$i]}-[0-9]" | sort))     #数组SOFT3赋值=(rpm -qa |grep ^anaconda-core-[0-9]|sort)
++ rpm -qa
++ sort
++ grep '^anaconda-core-[0-9]'
+ declare -a SOFT3
+ ((  2 < 2  ))
+ ((  2 > 2  ))
+ ((  2 == 2  ))      #刚好有两个包
+ [[ x86_64 == i686 ]]     #第一个包后缀是x86_64
+ [[ x86_64 == i686 ]]    #第二个包后缀是x86_64
+ echo 'anaconda-core-21.48.22.121-1.el7.centos.x86_64 can2 delete'      #输出能删除
+ ..........................省略

Script output error : script output file a total of 52 lines are able to delete the software, several of which are incorrect due to an error caused by software name, as follows:

Error 1: Software name: characters - Numbers - Character - the version number of an error of judgment leading to
the Java-1.8.0-openjdk-1.8.0.222.b10-0.el7_6.x86_64 CAN1 the Delete
the Java-1.8.0-openjdk-1.8.0.222. Delete CAN1 b10-0.el7_6.x86_64
SOFT2 [$ I] = $ {the SOFT1 [$ I] %% - [0-9]} * # problem in the capture software name, SOFT2 = java, the right should be SOFT2 = java-1.8.0-openjdk.

2 Error: wrong end of the name of the software, or the software is not to .X86 other end of the
gpg-pubkey-0c1289c0-58c6ad7d CAN1 the Delete
gpg-pubkey-0c1289c0-58c6ad7d CAN1 the Delete
gpg-pubkey-0c1289c0-58c6ad7d CAN1 the Delete
giving SOFT1 assignment the time required to filter out this does not end with the suffix .X86 or other software

Summary : rarely used array in your script, by this script deepened grasp and application of the array. 1 do not know how to solve this problem the wrong script output, most of the software can correctly remove the version number, the name of the individual software will not work, I feel there will always be loopholes. The script is mainly applied to practice an array, but also from over two thousand software which find duplicate software, although there are some errors, but it can also find duplicate software better than with your eyes, shining on the output file to remove the software will be a lot easier .

Guess you like

Origin blog.51cto.com/pkimin3/2437158