本文需要實現的功能如下:某文件夾下具有由按數字編號命名的文件夾,需要刪除除最大編碼外的文件。
具體實現
大致思路:循環遍歷該文件夾下所有文件,正則匹配出最大編碼文件;然后循環文件,刪除除最大編碼外的文件。
實現代碼如下:
#!/bin/bash function getdir(){ max=0 DATEPATTERN="^[0-9]*$" for element in `ls $1` do if [[ "$element" =~ $DATEPATTERN ]] then if [ `expr $max - $element` -lt 0 ] then max=$element fi fi done for element in `ls $1` do if [[ "$element" =~ $DATEPATTERN ]] then if [ $max != $element ] then rm -rf element fi fi done } root_dir="/root/cloud/builds" getdir $root_dir
實現效果:文件夾:/root/cloud/builds
執行腳本后:
用到的Shell基本知識
1. 變量
shell腳本的變量聲明通過“=”進行賦值,與C++或java不同,變量名、值與等號不能有空格,否則無法識別該變量。如
var=10 var1="qwert" var2='qwert'
echo $var #輸出 10
echo $var1 #輸出 qwert
echo $var2 #輸出 qwert
獲取變量中的值,采用“$變量名”格式。
2. 字符串
聲明字符串可以采用雙引號或單引號,但兩者有一些區別
單引號:1. 單引號中的字符會原樣輸出,其中的變量不起作用; 2. 單引號中不能使用轉義字符,會報錯;
雙引號:1. 可以包含變量並取值;2. 可以包含轉義字符
#!/bin/bash a=10 val='hello world $a' echo "單引號:"$val val='hello 'world' $a' echo "單引號+單引號 = 拼接:"$val #val='hello \'world\' $a' #echo $val #報錯:/usercode/file.sh: line 9: unexpected EOF while looking for matching `'' val="hello 'world' $a" echo "雙引號+單引號 = 輸出單引號:"$val val="hello "world" $a" echo "雙引號+雙引號 = 拼接:"$val val="hello \"world\" $a" echo "雙引號+雙引號轉義字符 = 輸出雙引號:"$val val="hello "$a"world" echo "雙引號+變量 = 拼接:"$val
輸出結果:
單引號:hello world $a 單引號+單引號 = 拼接:hello world $a 雙引號+單引號 = 輸出單引號:hello 'world' 10 雙引號+雙引號 = 拼接:hello world 10 雙引號+雙引號轉義字符 = 輸出雙引號:hello "world" 10 雙引號+變量 = 拼接:hello 10world
字符串拼接問題
(1)字符串拼接賦值給變量:雙引號或者單引號拼接的時候,如果子字符串完全為純字符串,之間可以有空格;如果存在變量,則變量與字符串之間不可以有空格;
(2)字符串拼接echo輸出:可以有空格。如echo "hello" $a 'world' 輸出:hello 10 world
3. 傳遞參數
腳本函數獲取參數的格式為:$n,n表示第n個參數,如$1表示獲取第一個參數,$2表示獲取第二個參數。。。。$0表示獲取執行腳本名
4. 基本運算
原生的bash不能進行簡單的數學計算,可以通過命令實現,如awk或expr。
各種運算規則可參考菜鳥教程:http://www.runoob.com/linux/linux-shell-basic-operators.html
本文中運用到的計算包括:減法計算、不等判斷、小於判斷,如[ `expr $max - $element` -lt 0 ]、[ $max != $element ]
5. 流程控制
(1)條件判斷:
if condition then ...... elif then ...... else ...... fi
(2)for循環
for var in item1 item2 ... itemN do command1 command2 ... commandN done
具體參考:http://www.runoob.com/linux/linux-shell-process-control.html
6. 正則表達式
本文中使用的正則表達式為正整數,如"^[0-9]*$",以^開始、$結束,[0-9]標識0到9之間的任意數字,*代表由前邊字符0個或以上個字符組成。具體,可參考http://www.jb51.net/article/94354.htm或相關書籍。
判斷目標是否匹配正則表達式,采用雙方括號和 =~,如 [[ "$element" =~ $DATEPATTERN ]]
7. #!/bin/bash
#!為約定標記,告訴系統該腳本需要什么解釋器來執行,Linux下默認使用bash,可在 /bin目錄下查看到bash文件,如下圖:
所有需要執行的shell腳本,都需要將其寫在第一行。
總結
- 需要花點時間學習下shell的基本語法和命令,可看菜鳥教程,也可看《Shell編程從入門到精通》
- 在shell腳本中使用rm命令的時候,也需要小心,操作不慎可能導致系統掛掉,可看bash腳本中使用rm命令時的致命誤區的講述
2018年1月17號
近日向Maven私庫Nexus中部署jar包時,日志文件顯示 not enough space,即磁盤空間不足,采用df -hl查看Linux磁盤使用情況,發現磁盤使用率100%。此時需要刪除一些歷史不用的jar包(包括*.jar *.pom *.jar.md5等),為了能夠自動化刪除,借助上邊思路書寫腳本。
根據需要批量刪除的文件的文件名包含序列數字,如ssc_base-0.0.1-20180117.014325-32.jar。需要做的工作:(1)需要采用識別文件名的正則表達式;(2)截取文件名中的數字;(3)將文件批量刪除
1 #!/bin/bash 2 function getdir(){ 3 max=0 4 DATEPATTERN="^[._A-Za-z0-9-]*-[0-9]*.pom$" 5 for element in `ls $1` 6 do 7 if [[ "$element" =~ $DATEPATTERN ]] 8 then 9 num=$element 10 num=${num##*-} 11 num=${num%%.*} 12 if [ `expr $max - $num` -lt 0 ] 13 then 14 max=$num 15 fi 16 fi 17 done 18 19 echo "********delete jar from $1,the max="$max 20 21 for element in `ls $1` 22 do 23 if [[ "$element" =~ $DATEPATTERN ]] 24 then 25 num=$element 26 num=${num##*-} 27 num=${num%%.*} 28 if [ $max != $num ] 29 then 30 echo rm -rf $1"/"*-$num.* 31 rm -rf $1"/"*-$num.* 32 fi 33 34 fi 35 done 36 } 37 38 root_dir="/usr/src/sonatype-work/nexus/storage/snapshots/yyssc/ssc_base/0.0.1-SNAPSHOT" 39 getdir $root_dir
(1)正則表達式:^[._A-Za-z0-9-]*-[0-9]*.pom$,匹配ssc_base-0.0.1-20180117.014325-32.pom
(2)截取文件.pom前的序列數字:對應9-11行,第10行 num##*-,去除“-”之前的所有字符(結果32.pom);第11行num%%.*,去除“.”之后的所有字符(結果32);參考Shell腳本8種字符串截取方法總結
(3)文件批量刪除:注意路徑寫全,rm -rf $1"/"*-$num.*