本篇內(nèi)容介紹了“shell腳本中數(shù)組的用法”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
我們提供的服務(wù)有:成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、微信公眾號(hào)開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、虞城ssl等。為成百上千企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的虞城網(wǎng)站制作公司
問題描述:某個(gè)員工的linux系統(tǒng)有大量重復(fù)的軟件(版本不同),導(dǎo)致使用yum安裝軟件時(shí)報(bào)錯(cuò)?,F(xiàn)在需要將重復(fù)的軟件找出來(lái),將低版本的軟件刪掉。執(zhí)行rpm -qa | sort 顯示如下:
[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 #這是重復(fù)軟件的低版本 anaconda-tui-21.48.22.147-1.el7.centos.x86_64 #這是重復(fù)軟件的高版本 anaconda-widgets-21.48.22.147-1.el7.centos.0.1.x86_64 ..........省略 總共2586個(gè)軟件
要求:如上所示,需要將低版本的軟件刪除,如下是例外:
[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
雖然是重復(fù)軟件,但一個(gè)是x86_64,一個(gè)是i686,這樣不能刪除,只能刪除重復(fù)的_x86_64結(jié)尾的軟件
數(shù)組:腳本中用到了數(shù)組,下面是數(shù)組的部分內(nèi)容概述:
1.數(shù)組定義:
declare -a 數(shù)組名 #定義索引數(shù)組,下標(biāo)從0開始
declare -A 數(shù)組名 #定義關(guān)聯(lián)數(shù)組,下標(biāo)為任意字符
2.數(shù)組賦值與復(fù)制:
2.1.可以通過命令替換的方式給數(shù)組賦值: declare -a SOFT1=($(rpm -qa | sort)) #數(shù)組SOFT1保存著所有軟件
2.2.數(shù)組復(fù)制操作:linux2=(${linux1[@]}) #數(shù)組linux2復(fù)制了數(shù)組linux1的內(nèi)容
3.數(shù)組的字符串操作:
3.1.字符串的操作符可以用在數(shù)組上,如:${#string} 用于數(shù)組 ${#array[@]},等等等等。
3.2.數(shù)組遍歷: for i in ${!SOFT[@]} #注意加上感嘆號(hào)可以遍歷數(shù)組中的值,假設(shè)SOFT的下標(biāo)最大是2586,通過for循環(huán)可以遍歷完數(shù)組,i的值從0依次到2586。
腳本內(nèi)容:
#!/bin/bash declare -a SOFT1=($(rpm -qa | sort)) #數(shù)組SOFT1保存所有軟件名稱 for i in ${!SOFT1[*]} #遍歷數(shù)組SOFT1 do declare -a SOFT2[$i]=${SOFT1[$i]%%-[0-9]*} #數(shù)組SOFT2復(fù)制數(shù)組SOFT1的部分內(nèi)容,%%是字符串截取符號(hào),相當(dāng)于去掉軟件的版本號(hào),只保留軟件名稱 done for i in $(seq 0 $((${#SOFT2[@]}-1))) #遍歷數(shù)組SOFT2 do let "j=$i+5" for (( ;i<j;j--)) #i小于j時(shí)跳出循環(huán),循環(huán)執(zhí)行5次 do if [ "${SOFT2[$i]}" == "${SOFT2[$j]}" ] #測(cè)試是否有重復(fù)軟件 then declare -a SOFT3=($(rpm -qa | grep "^${SOFT2[$i]}-[0-9]" | sort)) #如果軟件有重復(fù),執(zhí)行rpm -qa | grep 重復(fù)軟件名,賦值給數(shù)組SOFT3 if (( "${#SOFT3[@]}" < 2 )) #檢測(cè)數(shù)組SOFT3的下標(biāo)個(gè)數(shù)是否小于2(多加一層保險(xiǎn)) then echo "${SOFT2[$i]} no repeat version" >>/tmp/soft && continue #小于2輸出該軟件沒有重復(fù)的版本 elif (( "${#SOFT3[@]}" > 2 )) #如果下標(biāo)大于2,也就是(rpm -qa | grep 重復(fù)軟件)有多于2個(gè)軟件 then X86=0 I686=0 #初始化兩個(gè)變量,用于后面比較 for i in ${!SOFT3[*]} #遍歷數(shù)組SOFT3 do [[ "${SOFT3[$i]##*.}" == "i686" ]] && I686=$((I686+1)) || X86=$((X86+1)) #如果軟件名結(jié)尾是i686,那么變量I686加1,否則X86加1 done (( "$X86" >= "$I686" )) && echo "${SOFT3[0]} can1 delete" >>/tmp/soft #如果X86值大于I686,輸出軟件能夠刪除 elif (( "${#SOFT3[@]}" == 2 )) #如果下標(biāo)等于2,也就是(rpm -qa | grep 重復(fù)軟件)有兩個(gè) then [[ "${SOFT3[0]##*.}" == "i686" || "${SOFT3[1]##*.}" == "i686" ]] && { echo "${SOFT3[0]} only two packages but has I686" >>/tmp/soft ; continue ; } #兩個(gè)軟件里只要有1個(gè)是i686結(jié)尾的,輸出不能刪除 echo "${SOFT3[0]} can2 delete" >>/tmp/soft fi fi done done
腳本說(shuō)明:
1.數(shù)組SOFT1保存所有軟件的完整名稱,數(shù)組SOFT2是通過數(shù)組復(fù)制加上字符串的替換,截取出不帶版本名稱的軟件名,比如 SOFT1[4]=abrt-addon-ccpp-2.1.11-52.el7.centos.x86_64, SOFT2[4]=abrt-addon-ccpp。
2.利用for循環(huán)遍歷數(shù)組SOFT2來(lái)檢測(cè)那些是重復(fù)軟件,如下:
for i in $(seq 0 $((${#SOFT2[@]}-1))) #遍歷數(shù)組SOFT2 do let "j=$i+5" #j比i大5,用于測(cè)試某個(gè)軟件名與它后面的5個(gè)軟件名是否相等,因?yàn)槭峭ㄟ^rpm -qa | sort排序過,所以軟件名都是按照字母順序排的,比較5個(gè)就可以了。 for (( ;i<j;j--)) do if [ "${SOFT2[$i]}" == "${SOFT2[$j]}" ] #比較是否有重復(fù)軟件名
3.如果有重復(fù),需要處理軟件后綴名的問題,只有重復(fù)的以X86結(jié)尾的軟件名才輸出該軟件可以刪除。利用數(shù)組SOFT3=($(rpm -qa | grep "^${SOFT2[$i]}-[0-9]" | sort)) 來(lái)保存搜索出的重復(fù)軟件,然后在進(jìn)行判斷比較
腳本輸出結(jié)果:輸出被重定向到文件里,文件內(nèi)容如下:
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行(有少數(shù)錯(cuò)誤,后面說(shuō)明)
腳本調(diào)試信息:sh -x 腳本名顯示的部分內(nèi)容如下:
+ SOFT1=($(rpm -qa | sort)) #數(shù)組SOFT1保存完整軟件名 ++ rpm -qa ++ sort + declare -a SOFT1 + for i in '${!SOFT1[*]}' #遍歷數(shù)組SOFT1 + declare -a 'SOFT2[0]=a52dec' #給數(shù)組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個(gè) ++ seq 0 2585 + for i in '$(seq 0 $((${#SOFT2[@]}-1)))' #遍歷數(shù)組SOFT2,測(cè)試哪些是重復(fù)軟件 + 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...不是一個(gè)重復(fù)軟件 + (( j-- )) + (( i<j )) + for i in '$(seq 0 $((${#SOFT2[@]}-1)))' #比較下一個(gè),數(shù)組下標(biāo)加1 + let j=1+5 ...........................................................................省略 + for i in '$(seq 0 $((${#SOFT2[@]}-1)))' + let j=35+5 #數(shù)組下標(biāo)到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 ']' #這里找到重復(fù)軟件 + SOFT3=($(rpm -qa | grep "^${SOFT2[$i]}-[0-9]" | sort)) #數(shù)組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 )) #剛好有兩個(gè)包 + [[ x86_64 == i686 ]] #第一個(gè)包后綴是x86_64 + [[ x86_64 == i686 ]] #第二個(gè)包后綴是x86_64 + echo 'anaconda-core-21.48.22.121-1.el7.centos.x86_64 can2 delete' #輸出能刪除 + ..........................省略
腳本輸出錯(cuò)誤:腳本輸出文件里總共有52行是能刪除的軟件,其中有幾個(gè)是錯(cuò)誤的,由于軟件名稱導(dǎo)致的錯(cuò)誤,如下:
錯(cuò)誤1: 軟件名稱: 字符-數(shù)字-字符-版本號(hào) 導(dǎo)致判斷錯(cuò)誤
java-1.8.0-openjdk-1.8.0.222.b10-0.el7_6.x86_64 can1 delete
java-1.8.0-openjdk-1.8.0.222.b10-0.el7_6.x86_64 can1 delete
SOFT2[$i]=${SOFT1[$i]%%-[0-9]*} #問題就在截取軟件名稱上,SOFT2=java, 正確的應(yīng)該是SOFT2=java-1.8.0-openjdk。
錯(cuò)誤2:錯(cuò)誤的軟件名稱結(jié)尾,該軟件沒有以.X86或其他結(jié)尾
gpg-pubkey-0c1289c0-58c6ad7d can1 delete
gpg-pubkey-0c1289c0-58c6ad7d can1 delete
gpg-pubkey-0c1289c0-58c6ad7d can1 delete
在給SOFT1賦值的時(shí)候需要過濾掉這種沒有以.X86或其他后綴結(jié)尾的軟件
總結(jié):很少在腳本中用到數(shù)組,通過這個(gè)腳本加深了對(duì)數(shù)組的掌握與應(yīng)用。不知道怎么解決腳本輸出中的錯(cuò)誤1這種問題,大部分的軟件都能正確去掉版本號(hào),個(gè)別的軟件名就不行,感覺總會(huì)有漏洞。該腳本主要在于練習(xí)數(shù)組的應(yīng)用,同時(shí)也能從二千多個(gè)軟件里面找出重復(fù)軟件,雖然有個(gè)別錯(cuò)誤,但也會(huì)比用眼睛找重復(fù)軟件好,對(duì)照著輸出文件來(lái)刪除軟件會(huì)輕松很多。
“shell腳本中數(shù)組的用法”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
文章標(biāo)題:shell腳本中數(shù)組的用法
當(dāng)前網(wǎng)址:http://www.rwnh.cn/article46/jicgeg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營(yíng)銷型網(wǎng)站建設(shè)、Google、App設(shè)計(jì)、標(biāo)簽優(yōu)化、品牌網(wǎng)站制作、網(wǎng)站策劃
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)