檢測壓縮包並處理的Linux指令碼(解壓、批量修改檔名、匯入)分析

宋哥發表於2017-02-15

iamlaosong文

郵件結算資料壓縮包由工作人員不定時從結算系統下載再FTP到指定的目錄,所以我需要一個指令碼,每天定時(用crontab)檢測是否有上傳的壓縮包,如果有,則解壓、截短檔名,匯入資料庫。之所以要截短檔名,是因為下載的壓縮包中的檔名除了含有結算日期和型別外,還包括生成時間及序列號,而這一部分我是不需要的(沒有規律和意義),所以要截去,以便於匯入程式處理。壓縮包分兩種:使用費和補償費,每個壓縮包有6個檔案,分別是出口分揀、進口分揀、航空、陸運、轉運和投遞。下面是指令碼並解釋幾個關鍵點

#timing job:unzip & import costs datafile by iamlaosong 20170215  
#!/bin/sh

BAKDIR=/home/oracle/ems_suan
BINDIR=/home/oracle/bin/sdpt_js
#OPDATE=`date -d '-1 day' +%Y%m%d`

cd ${BAKDIR}
# OPDATE=today - seq
for i in $(seq 45 -1 7)
do
  OPDATE=`date -d "-$i day" +%Y%m%d` 
  echo ${OPDATE}
  # process SYF zipfile
  zipfile=${OPDATE}*SYF*.zip
  if [ -f ${zipfile} ]; then
    unzip ${zipfile}
    for tfile in ${OPDATE}*SYF*.txt
    do
      tshort=${tfile%SYF*.txt}SYF.txt
      if [ ${tfile} != ${tshort} ]; then
        mv ${tfile} ${tshort}
      fi
    done
    [ ! -d ${OPDATE} ] && mkdir -p ${OPDATE}
    rename _NBCL _ ${OPDATE}*SYF.txt
    mv ${OPDATE}*SYF.txt ${OPDATE}
    mv ${zipfile} all_zip
    cd ${BINDIR}
    ./jsimp.sh ${OPDATE} SYF >/dev/null
    cd ${BAKDIR}
  fi
  # process BCF zipfile
  zipfile=${OPDATE}*BCF*.zip
  if [ -f ${zipfile} ]; then
    unzip ${zipfile}
    for tfile in ${OPDATE}*BCF*.txt
    do
      tshort=${tfile%BCF*.txt}BCF.txt
      if [ ${tfile} != ${tshort} ]; then
        mv ${tfile} ${tshort}
      fi
    done
    [ ! -d ${OPDATE} ] && mkdir -p ${OPDATE}
    rename _NBCL _ ${OPDATE}*BCF.txt
    mv ${OPDATE}*BCF.txt ${OPDATE}
    mv ${zipfile} all_zip
    cd ${BINDIR}
    ./jsimp.sh ${OPDATE} BCF >/dev/null
    cd ${BAKDIR}
  fi
done
1、for i in $(seq 45 -1 7)

產生一個45到7的序列,用於產生距當天多少天的日期,以便檢測那個日期的壓縮包是否存在。

2、tshort=${tfile%SYF*.txt}SYF.txt

產生一個短檔名,將多餘的不確定部分截掉,詳細見Linux中如何批量截短檔名
3、rename _NBCL _ ${OPDATE}*SYF.txt

批量修改檔名,將檔名中的部分字元改成其它字元,見linux下批量修改檔名,本例是為了去掉一些字元。

4、zipfile=${OPDATE}*SYF*.zip

這個賦值有點意思,如果檔案存在,其中的萬用字元“*”會轉換成相應的字元,如果不存在,則將“*”直接賦給變數。

5、匯入程式執行較慢,如果上傳的壓縮包過多,就會發生頭天指令碼還沒結束,第二天又會定時啟動一個新的指令碼,為避免此事的發生,指令碼前面應該加一段檢測程式碼,如果有匯入程式,則退出處理,程式碼如下:

sdpt=$(ps -ef|grep sdpt_js)
sdpt=${sdpt#*./}
if [ ${sdpt:0:7}="sdpt_js" ]; then
  echo The import program is running.
  exit
fi

其中${sdpt#*./}是擷取“./”後面的字串,而${sdpt:0:7}則是取前7個字元,如果是“sdpt_js”就退出處理。

6、 [ ! -d ${OPDATE} ] && mkdir -p ${OPDATE} 

這是兩個連續的命令,前一個是檢測目錄是否存在,後一個是建立目錄。“&&”的意思是前一個命令如果執行成功,就執行後一個命令,本例中就是如果目錄不存在(注意其中的感嘆號表示“非”)就建立目錄。類似的還有“||”,表示前一個命令如果執行不成功,就執行後一個命令,所以,這個程式碼也可以寫成:

 cd ${OPDATE} || mkdir -p ${OPDATE} 


==============================================


實際應用過程中發現根據序列生成日期的方式檢測壓縮檔案並處理存在一個缺陷,就是有時壓縮包上傳的時間太遲了,導致檔案不在序列生成的日期範圍,壓縮檔案處理不到,還需要人工處理,所以需要改進處理辦法。考慮到檔名中含有日期,現在改為直接檢測壓縮檔案,提取檔名稱中的日期,然後進行處理,這樣就和上傳日期無關了。

指令碼如下:

#timing job:unzip & import costs datafile by iamlaosong 20170623  
#!/bin/sh

sdpt=$(ps -ef|grep sdpt_js)
sdpt=${sdpt#*./}
if [ "${sdpt:0:7}" = "sdpt_js" ]; then
  echo The import program is running.
  exit
fi

. /home/oracle/.bash_profile
BAKDIR=/home/oracle/ems_suan
BINDIR=/home/oracle/bin/sdpt_js
#OPDATE=`date -d '-1 day' +%Y%m%d`

cd ${BAKDIR}
for zipfile in *.zip
do
  OPDATE="${zipfile:0:8}" 
  echo ${OPDATE}
  # process SYF zipfile
  if [[ ${zipfile} =~ "SYF" ]]; then
    echo  ${zipfile}
#    read -p "SYF file: press enter to continue..." var
    unzip ${zipfile}
    for tfile in ${OPDATE}*SYF*.txt
    do
      tshort=${tfile%SYF*.txt}SYF.txt
      if [ ${tfile} != ${tshort} ]; then
        mv ${tfile} ${tshort}
      fi
    done
    [ ! -d ${OPDATE} ] && mkdir -p ${OPDATE}
    rename _NBCL _ ${OPDATE}*SYF.txt
#    read -p "SYF file: press enter to continue..." var
    mv ${OPDATE}*SYF.txt ${OPDATE}
    mv ${zipfile} all_zip
    cd ${BINDIR}
    ./jsimp.sh ${OPDATE} SYF >/dev/null
    cd ${BAKDIR}
  fi
  # process BCF zipfile
  if [[ ${zipfile} =~ "BCF" ]]; then
    echo  ${zipfile}
#    read -p "BCF file: press enter to continue..." var
    unzip ${zipfile}
    for tfile in ${OPDATE}*BCF*.txt
    do
      tshort=${tfile%BCF*.txt}BCF.txt
      if [ ${tfile} != ${tshort} ]; then
        mv ${tfile} ${tshort}
      fi
    done
    [ ! -d ${OPDATE} ] && mkdir -p ${OPDATE}
    rename _NBCL _ ${OPDATE}*BCF.txt
#    read -p "BCF file: press enter to continue..." var
    mv ${OPDATE}*BCF.txt ${OPDATE}
    mv ${zipfile} all_zip
    cd ${BINDIR}
    ./jsimp.sh ${OPDATE} BCF >/dev/null
   cd ${BAKDIR}
  fi
done

"[[ ]]" 判斷命令,比單箇中括號更通用,支援字串的模式匹配,使用=~操作符時甚至支援shell的正規表示式。
"=~"正則式匹配符號,利用它可以判斷左邊的字串是否包含右邊的字串。



相關文章