俺自己写的一个ftp shell,用了很多技巧哦awk,sed等等

来源:互联网 发布:威克姆阿贝女校知乎 编辑:程序博客网 时间:2024/04/26 14:59

#判断文件是否存在
isFileExisted()
{
   NEED_CHECK_FILE_DIR=$1
   NEED_CHECK_FILE=$2
   FILE_COUNT=`find ${NEED_CHECK_FILE_DIR} -name "${NEED_CHECK_FILE}" | wc -l`
   if [ ${FILE_COUNT} -eq "1" ]
   then
      return 0
   else
      return 1;
   fi
}

#判断是否还要下载文件
isNeedDownloadFile()
{
   checkfile_dir=$1
   ftp_over_checkfile=$2
   cd ${checkfile_dir}
   #如果标识所有数据下载完成的文件已经生成,那么就无需再次下载
   #反之就需要下载
   if isFileExisted ${checkfile_dir} ${ftp_over_checkfile}
   then
         echo "标识当日所有数据下载成功的文件 ${ftp_over_checkfile} 已经生成";
         return 1;
   else
         echo "标识当日所有数据下载成功的文件 ${ftp_over_checkfile} 还没有生成";
         return 0;
   fi    
}


#构建新的校验文件,因为校验文件本身的格式是
#因为远程机上的校验文件格式是
# 499272 11962671 193717536 dvc_20080323221606_000002.dat
# 498943 12217445 193589884 dvc_20080323003959_000001.dat
#  33777  860564 13105476 dvc_20080323003959_000002.dat
# end date 20080323
# 而我们只关心实际的文件名,所以在这里我们构建一个只有文件名的文件
# 即这种格式
# dvc_20080323112505_000006.dat
# dvc_20080323112505_000007.dat
# dvc_20080323112505_000008.dat
# dvc_20080323112505_000009.dat
# dvc_20080323112505_000010.dat
# 这种格式的好处就是方便了比较,因为我们的装载校验文件格式也是如此
#
#
buildNewCheckFile()
{
   checkfile_dir=$1
   remote_ftp_checkfile=$2
   new_ftp_checkfile=$3
   #因为这时还不能表明ftp下载全部数据送达,只能表示服务器端的当然的数据已经全部准备好
   #所以此时名称加一个.tmp后缀,一旦下载真正成功,就去掉.tmp后缀,形成真正的ftp_over_checkfile
   ftp_over_checkfile_tmp=$4.tmp
   data_time=$5
  
 #  echo "${checkfile_dir}"
 #  echo "${remote_ftp_checkfile}"
#   echo "${new_ftp_checkfile}"
#  echo "${ftp_over_checkfile}"
#  echo "${data_time}"
    
   #最后一行的格式
    expect_string="end date ${data_time}"
    lastrow_content="";
  
   cd ${checkfile_dir}
   #读取最后一行的内容
   lastrow_content=`sed -n '$p' ${remote_ftp_checkfile}`
   #如果最后一行于我们期待的结束标志一致
   #就去除最后一行,从整个文件中取第4个字段打印到新的校验文件中,同时生成一个FTP下载完成的校验文件
   #如果不一致,从整个文件中取第4个字段打印到新的校验文件中
      echo "${expect_string}"
      echo "${lastrow_content}"
   if [ "${lastrow_content}" = "${expect_string}" ]
   then
       echo "结束标记${expect_string}出现,表明远端机上当日数据准备完毕"
       sed '$d' ${remote_ftp_checkfile}| awk '{print$4}' > ${new_ftp_checkfile};
       touch  ${ftp_over_checkfile_tmp};
       echo "生成ftp下载完成的临时文件${ftp_over_checkfile_tmp}"
   else
        echo "结束标记${expect_string}还没有出现,表明远端机上当日数据还没有准备完毕"
        sed -n '1,$p' ${remote_ftp_checkfile} | awk '{print$4}'  > ${new_ftp_checkfile}
   fi
}

#比较校验文件,来判断还有哪些文件需要下载
compareCheckFile()
{
    checkfile_dir=$1
    new_ftp_checkfile=$2
    success_ftp_checkfile=$3
    need_download_file=$4
    data_time=$5

    EXPECT_STRING="end date ${data_time}"
    LAST_ROW_CONTENT="";
    #判断FTP校验文件是否存在,如果存在,证明至少下载过一次
    #如果存在就与当前最新FTP校验文件比较,生成最新的记录有 需要下载的文件名列表的文件
    #如果不存在,证明还没有下载过,直接拷贝最新FTP校验文件 生成 需要下载的文件名列表的文件
   if isFileExisted ${checkfile_dir} ${success_ftp_checkfile}
   then
        #将最新需要下载的文件名放在need_download_file中
       diff -c ${new_ftp_checkfile} ${success_ftp_checkfile} | sed -n '/^[-]/'p | sed '/^---/d' |sed 's/-[ ]//g' > ${need_download_file}
   else
       cp ${new_ftp_checkfile} ${need_download_file}
   fi
}


#下载check文件
downloadCheckFile()
{
   checkfile_dir=$1  #下载到哪个目录
   need_download_file=$2
  
   remote_host=$3
   remote_dir=$4
   username=$5
   userpwd=$6
  
   cd ${checkfile_dir};
   (echo "user ${username} ${userpwd}"
    echo "cd   ${remote_dir}"       
    echo "get  ${need_download_file}"
    echo "by")|ftp -v -i -n ${remote_host} > /dev/null
   
    echo "下载校验文件文件成功"
}

#下载数据文件
downloadDataFile()
{
   checkfile_dir=$1
   remote_ftp_checkfile=$2
   need_download_file=${checkfile_dir}/${remote_ftp_checkfile}.diff
   new_ftp_checkfile=${checkfile_dir}/${remote_ftp_checkfile}.new
   success_ftp_checkfile=${checkfile_dir}/${remote_ftp_checkfile}.success
   move_file=${checkfile_dir}/${remote_ftp_checkfile}.move
  
    ftp_over_checkfile=${remote_ftp_checkfile}.over
    ftp_over_checkfile_tmp=${ftp_over_checkfile}.tmp
  
   #下载到哪个目录
   download_dir=$3
   #转换目录,即转换所抽取的文件都在这个目录,这里面的文件肯定都是正确,即大小肯定正确
   transform_dir=$4
    
   remote_host=$5
   remote_dir=$6
  
   username=$7
   userpwd=$8
 
   cd ${download_dir};
    echo "远程目录是"${remote_dir};
   echo "本地下载目录是"${download_dir};
 

 #查看还有那些文件需要下载,然后依次下载
   for file_name in `awk '{print $1}' ${need_download_file}`
    do
    (echo "user ${username} ${userpwd}"
     echo "cd ${remote_dir}"
     echo "get ${file_name}"
     echo "by")|ftp -v -i -n    ${remote_host}    > /dev/null
     #下载一个文件成功,就往成功文件列表中增加一条纪录
     echo "下载文件 ${file_name} 到临时目录 ${download_dir} 成功。"
     echo "${file_name}" >> ${success_ftp_checkfile}
     mv  ${file_name} ${transform_dir}
     echo "${file_name}" >> ${move_file}
     echo "从临时目录 ${download_dir} 移动文件 ${file_name} 到转换数据目录 ${transform_dir} 成功。"
    done

   cd ${checkfile_dir}
  
   #ftp_over_checkfile_tmp这个临时已经存在,表明服务器上当日数据已经全部准备完毕
   #然后在比较new_ftp_checkfile和success_ftp_checkfile,如果两个文件的行数一致,证明
   #那么下载完这批数据,所有数据实际已经全部下载,那么把临时文件名改为正确的文件名
    echo ${checkfile_dir}
    echo ${ftp_over_checkfile_tmp}
    if  isFileExisted  ${checkfile_dir}  ${ftp_over_checkfile_tmp}
    then
     new_ftp_filecount=`cat ${new_ftp_checkfile} | wc -l`
     success_ftp_filecount=`cat ${success_ftp_checkfile} | wc -l`
     echo  "${new_ftp_filecount}" 
     echo  "${success_ftp_filecount}" 
     if [ "${new_ftp_filecount}" -eq "${success_ftp_filecount}" ]
     then
      mv ${ftp_over_checkfile_tmp} ${ftp_over_checkfile};
      echo "ftp_over_checkfile文件生成,表明当日数据全部下载成功。"
     else
      echo "ftp_over_checkfile文件没有生成,表明当日数据还没有全部下载成功。"
     fi
    fi
}

#Move所有文件是否成功
isMoveAllFilesSuccess()
{
  
    move_file=$1
    success_ftp_checkfile=$2
    checkfile_dir=$3
 
    cd ${checkfile_dir}
 
     move_filecout=`cat ${move_file} | wc -l`
 
     success_ftp_filecount=`cat ${success_ftp_checkfile} | wc -l`  
 
     if [ "${move_filecout}" -eq "${success_ftp_filecount}" ]
     then
      return 0;
     else
       return 1;
     fi
}

#Move那些剩余文件,即没有成功的文件
#Move成功之后,那么积累成功移动文件列表的文件应当和已经成功下载的文件列表一致
#Move成功之后,并且生成一个Move.over文件,来表示当日文件全部移动成功
moveLeftFiles()
{
    data_tmp_dir=$1
    data_dir=$2
   
    checkfile_dir=$3
    success_ftp_file=$4
    move_file=$5
   
    need_move_file=${move_file}.diff
   
    cd ${checkfile_dir}
    move_filecount=`cat ${move_file} | wc -l`
    success_ftp_filecount=`cat ${success_ftp_checkfile} | wc -l`
     echo  "${move_filecount}" 
     echo  "${success_ftp_filecount}" 
     #判断两个文件是否匹配,如果数目一致,证明所有文件移动完毕
     #构建当前还需要移动,即没有被移动的文件列表
     if [ "${move_filecount}" -eq "${success_ftp_filecount}" ]
     then
        echo "所有文件已经移动完毕"
     else
        #将最新需要移动的文件名放在need_download_file中
       diff -c ${success_ftp_file} ${move_file} | sed -n '/^[-]/'p | sed '/^---/d' |sed 's/-[ ]//g' > ${need_move_file}
       #开始移动剩余文件
    for file_name in `awk '{print $1}' ${need_move_file}`
    do
      #根据文件列表依次移动文件
      mv ${data_tmp_dir}/${file_name}  ${data_dir}
      echo "${file_name}" >> ${move_file}
      echo "从临时目录 ${data_tmp_dir} 移动文件 ${file_name} 到转换数据目录 ${transform_dir} 成功。"
    done
     fi

   
    #生成移动终止文件
    cd ${checkfile_dir}
    cp ${success_ftp_checkfile}  ${move_file}
  
}

 

CONFIG_FILE=/essbase/etl/test/shell/bill.cfg
LOCAL_CHECKFIIE_DIR=`awk -F "=" '$1=="LOCAL_CHECKFIIE_DIR"  {print $2}' ${CONFIG_FILE}`

REMOTE_CHECKFIIE_DIR=`awk -F "=" '$1=="REMOTE_CHECKFIIE_DIR"  {print $2}' ${CONFIG_FILE}`
REMOTE_HOST=`awk -F "=" '$1=="REMOTE_HOST"  {print $2}' ${CONFIG_FILE}`
USER_NAME=`awk -F "=" '$1=="USER_NAME"  {print $2}' ${CONFIG_FILE}`
PASSWORD=`awk -F "=" '$1=="PASSWORD"  {print $2}' ${CONFIG_FILE}`

START_DATA_TIME=$1 #20080326

REMOTE_FTP_CHECKFIIE=$2  #dvc20080326.check
REMOTE_DATAFILE_DIR=$3

LOCAL_NEW_FTP_CHECKFILE=${REMOTE_FTP_CHECKFIIE}.new  #dvc20080323.check.new
LOCAL_SUCCESS_FTP_CHECKFILE=${REMOTE_FTP_CHECKFIIE}.success  #
FTP_OVER_CHECK_FILE=${REMOTE_FTP_CHECKFIIE}.over #dvc20080323.check.over

#记录Move成功文件列表的文件
MOVE_SUCCESS_CHECKFILE=${REMOTE_FTP_CHECKFIIE}.move
MOVE_OVER_CHECKFILE=${MOVE_SUCCESS_CHECKFILE}.over

WAIT_DOWNLOAD_FILE=${REMOTE_FTP_CHECKFIIE}.diff
#最初就下载到临时文件,等到文件下载完成后,才mv这个文件到转换所用到的数据目录
LOCAL_DATAFILE_TMP_DIR=$4 #/essbase/etl/test/tmp
LOCAL_DATAFILE_DIR=$5  #/essbase/etl/test/data

 

cd ${LOCAL_CHECKFIIE_DIR}

echo "开始判断是否需要下载文件"
#如果对应数据时间的所有文件装载成功,会形成一个over文件来作为标识
#如果发现这个over文件,那么就不再下载对应数据时间的文件
#否则就一直下载文件
while  isNeedDownloadFile ${LOCAL_CHECKFIIE_DIR} ${FTP_OVER_CHECK_FILE}
do
   #开始下载远端的校验文件
  echo "Need download file"
  echo "开始下载远端校验文件"
  downloadCheckFile ${LOCAL_CHECKFIIE_DIR}  ${REMOTE_FTP_CHECKFIIE}   ${REMOTE_HOST}   ${REMOTE_CHECKFIIE_DIR}  ${USER_NAME}  ${PASSWORD} 
  echo "结束下载远端校验文件"

  cd $LOCAL_CHECKFIIE_DIR
  echo "开始构建新的check文件"
  #构建新的check文件
  buildNewCheckFile ${LOCAL_CHECKFIIE_DIR}  ${REMOTE_FTP_CHECKFIIE}  ${LOCAL_NEW_FTP_CHECKFILE} ${FTP_OVER_CHECK_FILE}   ${START_DATA_TIME}
  echo "结束构建新的check文件"

  echo "开始比较check文件"
  #比较check文件,生成最新的需要下载的文件列表,当然这个文件列表也是存在一个文件里面
  compareCheckFile ${LOCAL_CHECKFIIE_DIR} ${LOCAL_NEW_FTP_CHECKFILE}  ${LOCAL_SUCCESS_FTP_CHECKFILE} ${WAIT_DOWNLOAD_FILE} ${START_DATA_TIME}
  echo "结束比较check文件"

  echo "开始下载数据文件"
   downloadDataFile ${LOCAL_CHECKFIIE_DIR} ${REMOTE_FTP_CHECKFIIE} ${LOCAL_DATAFILE_TMP_DIR} ${LOCAL_DATAFILE_DIR} ${REMOTE_HOST} ${REMOTE_DATAFILE_DIR} ${USER_NAME} ${PASSWORD}
  echo "结束下载数据文件"
done
echo "结束判断是否需要下载文件"

echo "开始判断是否要移动剩余文件"
until isMoveAllFilesSuccess ${MOVE_SUCCESS_CHECKFILE}  ${LOCAL_SUCCESS_FTP_CHECKFILE}  ${LOCAL_CHECKFIIE_DIR}
do
    moveLeftFiles ${LOCAL_DATAFILE_TMP_DIR}  ${LOCAL_DATAFILE_DIR} ${LOCAL_CHECKFIIE_DIR} ${LOCAL_SUCCESS_FTP_CHECKFILE} ${MOVE_SUCCESS_CHECKFILE}   
sleep 600
done
echo "结束判断是否要移动剩余文件"
 
touch ${MOVE_OVER_CHECKFILE}
echo "Move全部文件的校验文件${MOVE_OVER_CHECKFILE}生成"

echo "${START_DATA_TIME}需要的转换数据全部准备完成"