#需要預先配置
#分隔符個數,文件小門限,顆粒度和超時時間已經放在“Tran_configue.ini”。
#輸出、輸出目錄要在一個磁盤分區下,否則大文件mv會導致IO增加很多
Input_path="/opt/small_file"
Output_path="/opt/big_file"
cd $CURRENT_PATH
CURRENT_PATH=`pwd`
#echo $CURRENT_PATH
dir_time=`date +%Y%m%d.%H%M%S`
if [ ! -d $dir_time ]
then
mkdir $dir_time
fi
if [ ! -d $Input_path ]
then
mkdir $Input_path
fi
#輸出目錄
if [ ! -d $Output_path ]
then
mkdir $Output_path
fi
#存放錯誤文件
if [ ! -d $CURRENT_PATH/Error ]
then
mkdir $CURRENT_PATH/Error
fi
today_time=`date +%Y%m%d`
log_file="Unite_${today_time}.log"
today_seconds=`date +%s`
echo "[ `date +%Y-%m-%d_%T` ][`hostname`][=================================Unite starts ]" >>./$log_file
cat Tran_configue.ini | while read LINE
do
prefix=`echo $LINE | awk '{printf $1}'`
FS_NUM=`echo $LINE | awk '{printf $2}'`
F_size=`echo $LINE | awk '{printf $3}'`
period_interval=`echo $LINE | awk '{printf $4}'`
time_out=`echo $LINE | awk '{printf $5}'`
### 過濾文件類型,循環處理,後面 "file_name" 從此處獲取。
#取一個文件,根據文件名的時間戳進行判斷它屬於哪個週期,同一個週期的文件合併。
#最右邊一個"_",取右邊,最右邊"."取左邊。
do
#從左邊數,最後一個"_",取右邊,"20151209.0800.dat"
date_time=${file_name##*_}
date_time1=${date_time%%.*}
date_time2=${date_time#*.}
date_time3=${date_time2%%.*}
day_senconds=`date +%s -d "${date_time1} ${date_time3}"`
#但是需要考慮時間,如果一個週期的文件本來就很小,後續沒有新文件,大小不滿足“大文件”,需要根據時間戳,判斷超時,直接挪動到輸出目錄。
#1800是半小時,900是15分鐘
#echo "period_interval : ${period_interval}"
#echo "hour_num : $hour_num"
period_time=`date +"%Y%m%d.%H%M" -d @${hour_num}`
#echo "period_time : $period_time"
new_file_name="${prefix}_${period_time}.${today_seconds}.dat"
#echo "new_file_name : $new_file_name"
#取得文件最大的列數,如果列數和定義的列數不一致,文件挪到Error文件夾
column_num=`awk 'BEGIN {FS=",";min_nf=10000;max_nf=0;final_nf=0}{if (NF > max_nf) {max_nf = NF}}{if (NF < min_nf) {min_nf = NF}} END{if (min_nf == max_nf){printf min_nf}else{printf 0}}' $file_name`
if [ ${FS_NUM} -ne ${column_num} ];
then
echo "[ `date +%Y-%m-%d_%T` ][`hostname`][$prefix] Column number of file: ${file_name} is not the same as ${FS_NUM}" >>./$log_file
mv $file_name $CURRENT_PATH/Error/
echo "[ `date +%Y-%m-%d_%T` ][`hostname`][$prefix] File: $file_name has been moved to ${CURRENT_PATH}/Error" >>./$log_file
continue
fi
#文件的時間戳是否已經距離當前處理時間比較長?
#如果首次啓動很多小文件都是超時間的,文件可能很大
then
echo "[ `date +%Y-%m-%d_%T` ][`hostname`][$prefix] File: $file_name is older than the time_out threadhold: ${time_out} seconds from now " >>./$log_file
cat $file_name >> ${Output_path}/${new_file_name}.tmp
echo "[ `date +%Y-%m-%d_%T` ][`hostname`][$prefix] cat $file_name >> ${Output_path}/${new_file_name}.tmp " >>./$log_file
rm -fr $file_name
continue
fi
#取得文件的大小,大於1G的文件不合並,直接挪動回原來文件夾
file_size=`du -k $file_name | awk '{printf $1}'`
#echo "file size is : $file_size"
if [ $file_size -gt $F_size ];
then
echo "[ `date +%Y-%m-%d_%T` ][`hostname`][$prefix] Size of file: ${file_name} is: ${file_size} K,which is greater than ${F_size} K" >>./$log_file
#直接挪動到輸出目錄(文件名加處理時間戳)
#從左邊數,最後一個"/",取右邊,去掉目錄
#tm_file_name=${file_name##*/}
#mv_file_name=${tm_file_name%.*}
#加上處理批次的時間戳(如果之前合併過,文件名中已經帶有時間戳,就會出現多個時間戳)
#mv $file_name ${Output_path}/${mv_file_name}.${today_seconds}.dat
#mv $file_name ${Output_path}/${tm_file_name}
cat $file_name >> ${Output_path}/${new_file_name}.tmp
echo "[ `date +%Y-%m-%d_%T` ][`hostname`][$prefix] cat $file_name >> ${Output_path}/${new_file_name}.tmp " >>./$log_file
rm -fr $file_name
continue
fi
cat $file_name >> $CURRENT_PATH/$dir_time/$new_file_name
echo "[ `date +%Y-%m-%d_%T` ][`hostname`][$prefix] cat $file_name >> $CURRENT_PATH/$dir_time/$new_file_name" >>./$log_file
rm -fr $file_name
done
########################################################
#原來輸出目錄的tmp文件,需要改名
if [ `ls ${Output_path}/*.dat.tmp | wc -l` -ne 0 ];
then
rename .dat.tmp .dat ${Output_path}/*.dat.tmp
echo "[ `date +%Y-%m-%d_%T` ][`hostname`][$prefix] Rename ${Output_path}/*.dat.tmp to ${Output_path}/*.dat " >>./$log_file
fi
##################################################################################################################
done
find ${CURRENT_PATH}/${dir_time}/ -empty -type f | xargs -i rm -r {}
if [ `ls ${CURRENT_PATH}/${dir_time}/*.dat | wc -l` -ne 0 ];
then
mv ${CURRENT_PATH}/${dir_time}/*.dat $Input_path/
fi
#目錄爲空,就刪除本次目錄
if [ "`ls -A $dir_time`" = "" ];
then
rmdir $dir_time
echo "[ `date +%Y-%m-%d_%T` ][`hostname`]TempDir: $dir_time is deleted " >>./$log_file
else
echo "[ `date +%Y-%m-%d_%T` ][`hostname`]TempDir: $dir_time is not Empty " >>./$log_file
fi
echo "[ `date +%Y-%m-%d_%T` ][`hostname`][=================================Unite is ended]" >>./$log_file
####################################################
vi Tran_configue.ini
web 17 50 1800 1800
stream 17 50 1800 1800
####################################################
1、數據文件所在目錄需要設置
web 17 50 1800 1800
##################
腳本可以放在crontab -e中定期執行。注意權限。
crontab -e
10,20,40,50 * * * * /bin/bash /opt/CatUnite/CatUnite.sh
##################
stream_20151209.1330.dat
web_20151209.1330.dat
stream_20151209.1332.1449663831.dat
stream_20151209.1337.1449663831.dat
web_20151209.1338.1449663831.dat
stream_20151210.1240.1449663831.dat
stream_20151210.1242.1449663831.dat
web_20151210.1320.1449663831.dat
stream_20151210.1320.1449663831.dat
####################################
QQ:455309894