linux shell 指令碼 曆史檔案清理指令碼,按天,按月,清理前N天的曆史檔案,刪除指定大小曆史檔案,曆史檔案歸檔清理__linux

來源:互聯網
上載者:User

不知道大家那有沒有要清理的這個事情。需要清理目錄曆史檔案。可能後續也會有很多其他地方需要清理曆史檔案,可能會用到。

我這兩天空閑寫了個指令碼,清理比較方便,有要進行清理的大量曆史檔案的話可以用。

 

指令碼用到的命令只有linux才有,像solaris等就不支援,所以只能在linux上運行。如果是nas儲存的話,可以掛載到一個linux主機上跑指令碼清理。

另外,指令碼尋找檔案用的是ls,但是ls也有最大檔案的限度(大概10w以內),如果每天檔案很多,每天都是10w+的,運行可能提示檔案數過多無法ls。

還有,指令碼內有個預設的限制,就是清理的檔案的建立日期是跟檔案名稱上的時間是相同的,如果是不同的話,是不會清理的,這是為了避免清理錯了。


我寫了兩個版本的清理指令碼,一個是直接清理檔案的clearfile.sh,一個是把檔案按天/月進行歸檔(歸檔成檔案夾或壓縮包形式)clearfile_ar.sh:


(一)單純清理檔案使用clearfile.sh

檔案名稱是帶有時間戳記的檔案,類似如下(或其他時間格式,後面描述)


按天/月清理:修改指令碼內的CLEAR_TYPE參數,D是天,M是月

如果是按月的話,指令碼按你輸入的月份進行整月清理,不會看你輸入的天的時間

清理指定期間內所有檔案

./clearfile.sh/wls/investop/tmp/ 20170515 20170516

清理指定期間內固定大小檔案(ls -l顯示的大小)

./clearfile.sh /wls/investop/tmp/ 20170515 20170516 40

其他檔案日期格式清理

指令碼預設(TRUNC_DATE_FLAG參數為N)是清理上面截圖這類格式的,沒有任何間隔符的檔案名稱。

如果檔案名稱是有其他間隔符的,如*2017_05_16*這種的。

首先需要調整下指令碼裡的trunc()方法,把標黃的年月日之間的分隔字元改成需要的分隔字元(按天和按月兩種哦)


然後再設定TRUNC_DATE_FLAG參數為Y,來讓指令碼使用你指定的日期格式清理


(二)歸檔方式清理曆史檔案,使用clearfile_ar.sh

使用方式與clearfile.sh相同,唯一不同的是要設定指令碼裡的DEL_FLAG參數。

按天/月清理同clearfile.sh

清理指定期間內所有檔案同clearfile.sh

清理指定期間內固定大小檔案         同clearfile.sh

其他檔案日期格式清理     同clearfile.sh

 

模式1:DEL_FLAG=N 指令碼只會把檔案按天 / 按月歸檔到以時間命名的檔案夾內,如


模式2DEL_FLAG=Y 把檔案歸檔成壓縮檔 *tar.gz ,並刪除歸檔的檔案夾




PS,對於大量需要清理的目錄,可以寫一個非常簡單的指令碼來批量執行,類似



但是要去掉指令碼裡的是否確認執行這個反饋,否則指令碼執行還是要你輸入Y。



~~~~~~~~~~~~~~~~~~指令碼如下~~~~~~~~~~~~~~~~~~

clearfile.sh

#!/bin/bash##################################參數設定################################TODAY=`date +%Y%m%d`DATE_BEGIN=`date +%Y%m%d`DATE_END=`date +%Y%m%d`DATE_FORMATION="%Y%m%d"FILESIZE=""COUNTING=0#需要手工設定,按月清理不會根據輸入日期的天清理,只能清理整個月。CLEAR_TYPE=M#需要手工設定,是否需要轉換日期格式,需要的話,要根據格式設定trunc()方法TRUNC_DATE_FLAG=Nif [ -f count.tmp ] thenecho "" > count.tmpfi##################################日期格式轉換,eg:trunc 20170512################################trunc(){if [ "D" = "$CLEAR_TYPE" ]thenOPR_DATE=`echo $1 | sed -r 's/^(.{4})(.{2})(.{2})$/\1_\2_\3/g'`elseOPR_DATE=`echo $1 | sed -r 's/^(.{4})(.{2})$/\1_\2/g'`fi}##################################按日清理遞迴################################dayclear(){ echo "================================" echo "day clear working on $DATE_END" doclear $DATE_END priday $DATE_END  if [ $DATE_END -lt $DATE_BEGIN ] then echo "================================" echo "Total cleard : $COUNTING " echo "dayclear end" return fi  dayclear }##################################按月清理遞迴################################monthclear(){ echo "================================" echo "clearfun working on $DATE_END" doclear $DATE_END primonth $DATE_END  if [ $DATE_END -lt $DATE_BEGIN ] then echo "================================" echo "Total cleard : $COUNTING " echo "monthclear end" return fi  monthclear }##################################前一日日期,eg:priday 20170421################################priday(){ SEC=`date -d $1 +%s` PRI_SEC=$[${SEC}-86400] PRI_DAY=`date -d @${PRI_SEC} +%Y%m%d` DATE_END=$PRI_DAY}##################################前一月日期,eg:primonth 201704################################primonth(){ #TMP_D=`echo $1 | cut -c 1-6` #TMP_D=${TMP_D}"01" TMP_D=`echo $1`"01" SEC=`date -d $TMP_D +%s` PRI_SEC=$[${SEC}-86400] PRI_MON=`date -d @${PRI_SEC} +%Y%m` DATE_END=$PRI_MON}##################################清理檔案################################doclear(){ #預設的日期格式,如20170512,201705 THE_DATE=$1 OPR_DATE=$1 #轉換OPR_DATE的日期格式,如2017-05-12,2017-05 if [ "Y" = ${TRUNC_DATE_FLAG} ] ; then  trunc $1 fi  echo "clearing" if [ "" == "${FILESIZE}"  ] then  #ROW=`ls -l *${OPR_DATE}* | awk  '{ print $9;output="ls -l "$9;system(output);}' | wc -l`  ls -ld --time-style +${DATE_FORMATION} *${OPR_DATE}* | grep -v archive | awk -v date_str=${THE_DATE} 'BEGIN{count=0}{if (date_str==$6) {count+=1;output="rm "$7;system(output);}}END{oo="echo "count" > count.tmp";system(oo);}'  ROW=`cat count.tmp`  COUNTING=$[ $COUNTING + $ROW ] else  #ROW=`ls -l *${OPR_DATE}* | awk -v the_size=${FILESIZE} '{if ($5==the_size) {output="ls -l "$9;system(output)}}' | wc -l`  ls -ld --time-style +${DATE_FORMATION} *${OPR_DATE}* | awk -v the_size=${FILESIZE} -v date_str=${THE_DATE} 'BEGIN{count=0}{if (the_size==$5 && date_str==$6) {count+=1;output="rm "$7;system(output);}}END{oo="echo "count" > count.tmp";system(oo);}'  ROW=`cat count.tmp`  COUNTING=$[ $COUNTING + $ROW ] fi echo "clear $THE_DATE finished, clear file $ROW "}######################################### main function## 判斷參數是否正確,可以輸入如下:## 清理所有檔案:clear 20150601 20161231 ## 清理固定大小位元組檔案:clear 20150601 20161231 40## 清理固定大小位元組檔案:clear 20150601 20161231 40########################################清理所有檔案,if [ $# -ne 3 ] && [ $# -ne 4 ]thenecho "請輸入正確的參數"echo "如清理/nfsc/hipo/bak目錄下,從2015年4月1號到2016年12月31號的所有檔案(預設按日清理):clearfile /nfsc/hipo/bak 20150401 20161231"echo "或清理清理/nfsc/hipo/bak目錄下,從2015年4月1號到2016年12月31號的大小為40位元組的檔案(預設按日清理):clearfile /nfsc/hipo/bak 20150401 20161231 40"exit 1elseDATE_BEGIN=$2DATE_END=$3FILESIZE=$4date -d $2 2>&-ERR1=$?date -d $3 2>&-ERR2=$?if [ $ERR1 -eq 1 ] || [ $ERR2 -eq 1 ]; then echo "date formation error, input the correct date string like 20170131." exit 1elif [ $DATE_BEGIN -gt $DATE_END ]; then  echo "BEGIN DATE is later than END DATE, please correct." exit 1elif [ $TODAY -lt $DATE_END ]; then echo "END DATE is later than NOW DATE, please correct"elif [ ! -d $1 ]; then echo "DIR $1 does not exist." exit 0fifi  cd $1 THEDIR=`pwd` echo ">>>>clear the DIR $THEDIR " echo ">>>>clear file between $DATE_BEGIN and $DATE_END." if [ "" == "${FILESIZE}"  ]; then  echo ">>>>every size of the files will be clear" else   echo ">>>>clear filesize only is ${FILESIZE}" fi if [ "D" == "${CLEAR_TYPE}"  ]; then  echo ">>>>clear set by DAY" else  echo ">>>>clear by MONTH" fi read -p "please confirm the information above,enter Y to continue, other to exit : " ANWSER #確認繼續 if [ ! -n "$ANWSER" ] || [ $ANWSER != Y ] then echo "exit" exit 0 fiecho "[`date +%Y%m%d-%H%M%S`]==START=="if [ "D" = "$CLEAR_TYPE" ]then echo "DAY clear begin " DATE_FORMATION="%Y%m%d" dayclearelse echo "MONTH clear begin " DATE_BEGIN=`echo $2 | cut -c 1-6` DATE_END=`echo $3 | cut -c 1-6` DATE_FORMATION="%Y%m" monthclearfiecho "[`date +%Y%m%d-%H%M%S`]==END=="

clearfile_ar.sh

#!/bin/bash##################################參數設定################################TODAY=`date +%Y%m%d`DATE_BEGIN=`date +%Y%m%d`DATE_END=`date +%Y%m%d`DATE_FORMATION="%Y%m%d"FILESIZE=""COUNTING=0#需要手工設定,按月清理不會根據輸入日期的天清理,只能清理整個月。CLEAR_TYPE=M#需要手工設定,是否刪除歸檔的檔案,只保留壓縮檔DEL_FLAG=N#需要手工設定,是否需要轉換日期格式,需要的話,要根據格式設定trunc()方法TRUNC_DATE_FLAG=Nif [ -f count.tmp ] thenecho "" > count.tmpfi##################################日期格式轉換,eg:trunc 20170512################################trunc(){if [ "D" = "$CLEAR_TYPE" ]thenOPR_DATE=`echo $1 | sed -r 's/^(.{4})(.{2})(.{2})$/\1_\2_\3/g'`elseOPR_DATE=`echo $1 | sed -r 's/^(.{4})(.{2})$/\1_\2/g'`fi}##################################按日清理遞迴################################dayclear(){ echo "================================" echo "day clear working on $DATE_END" doclear $DATE_END priday $DATE_END if [ $DATE_END -lt $DATE_BEGIN ] then echo "================================" echo "Total cleard : $COUNTING " echo "dayclear end" return fi  dayclear }##################################按月清理遞迴################################monthclear(){ echo "================================" echo "clearfun working on $DATE_END" doclear $DATE_END primonth $DATE_END  if [ $DATE_END -lt $DATE_BEGIN ] then echo "================================" echo "Total cleard : $COUNTING " echo "monthclear end" return fi  monthclear }##################################前一日日期,eg:priday 20170421################################priday(){ SEC=`date -d $1 +%s` PRI_SEC=$[${SEC}-86400] PRI_DAY=`date -d @${PRI_SEC} +%Y%m%d` DATE_END=$PRI_DAY}##################################前一月日期,eg:primonth 201704################################primonth(){ #TMP_D=`echo $1 | cut -c 1-6` #TMP_D=${TMP_D}"01" TMP_D=`echo $1`"01" SEC=`date -d $TMP_D +%s` PRI_SEC=$[${SEC}-86400] PRI_MON=`date -d @${PRI_SEC} +%Y%m` DATE_END=$PRI_MON}##################################清理檔案################################doclear(){ #預設的日期格式,如20170512,201705 THE_DATE=$1 OPR_DATE=$1 #轉換OPR_DATE的日期格式,如2017-05-12,2017-05 if [ "Y" = ${TRUNC_DATE_FLAG} ] ; then  trunc $1 fi #建立歸檔檔案夾 echo "clearing" if [ ! -d ${THE_DATE}"archive" ] ;then  mkdir "${THE_DATE}"archive ERR=$?  if [ 0 != ${ERR} ]; then  echo "failed to create archive dir under "`pwd`  exit 0  fi echo "created the archive directory ${THE_DATE}archive" chmod 777 ${THE_DATE}"archive" else  echo "the archive directory already exist ${THE_DATE}archive" fi  #如果要刪除曆史的歸檔檔案,判斷是否已經存在過曆史檔案的壓縮包 if [ -f "${THE_DATE}archive.tar.gz" ] && [ "Y" = "${DEL_FLAG}" ] ;then   echo "file ${THE_DATE}archive.tar.gz already exits, and again you choose to archive the file which had been archived ,this will cause the old tar.gz file tobe overwirted."  echo "you should confirm the date parameter you input, or you can mv the exits *.tar.gz file to other directory."  exit 0 fi  if [ "" == "${FILESIZE}"  ] then  ls -ld --time-style +${DATE_FORMATION} *${OPR_DATE}* | grep -v archive | awk -v date_str=${THE_DATE} 'BEGIN{count=0;}{if (date_str==$6) {count+=1;output="mv "$7" "date_str"archive/";system(output);}}END{oo="echo "count" > count.tmp";system(oo);}'  if [ "Y" = "${DEL_FLAG}" ] ; then   tar -cf - ${THE_DATE}"archive/" | gzip > ${THE_DATE}"archive.tar.gz"   rm -rf ${THE_DATE}"archive/"  fi  ROW=`cat count.tmp`  COUNTING=$[ $COUNTING + $ROW ] else  ls -ld --time-style +${DATE_FORMATION} *${OPR_DATE}* | grep -v archive | awk -v the_size=${FILESIZE} -v date_str=${THE_DATE} 'BEGIN{count=0;}{if (the_size==$5 && date_str==$6) {count+=1;output="mv "$7" "date_str"archive/";system(output);}}END{oo="echo "count" > count.tmp";system(oo);}'  if [ "Y" = "${DEL_FLAG}" ] ; then   tar -cf - ${THE_DATE}"archive/" | gzip > ${THE_DATE}"archive.tar.gz"   rm -rf ${THE_DATE}"archive/"  fi  ROW=`cat count.tmp`  COUNTING=$[ $COUNTING + $ROW ] fi  echo "clear $THE_DATE finished, clear file $ROW "}######################################### main function## 判斷參數是否正確,可以輸入如下:## 清理所有檔案:clear 20150601 20161231 ## 清理固定大小位元組檔案:clear 20150601 20161231 40## 清理固定大小位元組檔案:clear 20150601 20161231 40########################################清理所有檔案,if [ $# -ne 3 ] && [ $# -ne 4 ]thenecho "請輸入正確的參數"echo "如清理/nfsc/hipo/bak目錄下,從2015年4月1號到2016年12月31號的所有檔案(預設按日清理):clearfile /nfsc/hipo/bak 20150401 20161231"echo "或清理清理/nfsc/hipo/bak目錄下,從2015年4月1號到2016年12月31號的大小為40位元組的檔案(預設按日清理):clearfile /nfsc/hipo/bak 20150401 20161231 40"exit 1elseDATE_BEGIN=$2DATE_END=$3FILESIZE=$4date -d $2 2>&-ERR1=$?date -d $3 2>&-ERR2=$?if [ $ERR1 -eq 1 ] || [ $ERR2 -eq 1 ]; then echo "date formation error, input the correct date string like 20170131." exit 1elif [ $DATE_BEGIN -gt $DATE_END ]; then  echo "BEGIN DATE is later than END DATE, please correct." exit 1elif [ $TODAY -lt $DATE_END ]; then echo "END DATE is later than NOW DATE, please correct"elif [ ! -d $1 ]; then echo "DIR $1 does not exist." exit 0fifi  cd $1 THEDIR=`pwd` echo ">>>>clear the DIR $THEDIR " echo ">>>>clear file between $DATE_BEGIN and $DATE_END." if [ "" == "${FILESIZE}"  ]; then  echo ">>>>every size of the files will be clear" else   echo ">>>>clear filesize only is ${FILESIZE}" fi if [ "D" == "${CLEAR_TYPE}"  ]; then  echo ">>>>clear set by DAY" else  echo ">>>>clear by MONTH" fi read -p "please confirm the information above,enter Y to continue, other to exit : " ANWSER #確認繼續 if [ ! -n "$ANWSER" ] || [ $ANWSER != Y ] then echo "exit" exit 0 fiecho "[`date +%Y%m%d-%H%M%S`]==START=="if [ "D" = "$CLEAR_TYPE" ]then echo "DAY clear begin " DATE_FORMATION="%Y%m%d" dayclearelse echo "MONTH clear begin " DATE_BEGIN=`echo $2 | cut -c 1-6` DATE_END=`echo $3 | cut -c 1-6` DATE_FORMATION="%Y%m" monthclearfiecho "[`date +%Y%m%d-%H%M%S`]==END=="


歡迎各位博友提出更新意見。


謝謝


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.