1. 程式人生 > >將檔案內容逐行讀取處理並寫入對應檔案中

將檔案內容逐行讀取處理並寫入對應檔案中

場景:現有一個檔案裡面有大量的資料,約3.6G,4000多萬行,每行的資料格式是一樣的,共有9個域,如下:

3880961244329353 9 26 3862561814 2015-08-28 23:45:28 qinglei 2015-08-28 23:50:13

現在的需求是:將每一行資料按照倒數第二個域的日期來分類,相同日期的行寫入相應日期的檔案中,並且對檔名的日期進行處理(將”2015-08-28”修改為20150828,並以此命名檔名)

解決辦法一
剛開始沒有考慮到效率的問題,只是想實現它,所以寫了比較笨的方法,如下:

history_line_all_count=`cat /data0/userreport/activeprocess/activeprocess.history.log | wc -l
` echo $history_line_all_count for((i=1;i<=$history_line_all_count;i++)); do date=`awk 'NR=='$i' {print $(NF-1)}' /data0/userreport/activeprocess/activeprocess.history.log` date_e=`echo $date | sed 's/-//g'` activeprocess="activeprocess.$date_e" sed -n ''$i'p' /data0/userreport/activeprocess/activeprocess.history.log >> /usr/home/shixi_xiongchao1/activeprocess.history/$activeprocess
done

方法思路就是:首先先統計出檔案的行數(history_line_all_count),然後使用for迴圈對每行進行處理,處理的方式是使用awk讀取出指定行的倒數第二個域($(NF-1)),也就是日期,然後對日期使用sed處理,將”-“去掉,去掉後的日期組合成檔名(activeprocess),最後在用sed將此行讀取出來並寫入到組合好檔名的檔案中

注:此種方法效率極低,對於資料量很大的檔案來說根本不可行,運行了一夜,才分析出幾百K的資料,所以沒有辦法,重新考慮優化,所以想出了下面一種方法

解決辦法二
方法如下:

cat activeprocess.history.
log | awk '{print $0 >> "activeprocess.history/activeprocess."$(NF-1) }'

沒有看錯,就是一個命令,直接使用awk,因為awk本身就是逐行讀取內容的,所以就不用再for的,awk讀取每一行的時候將倒數第二個域($(NF-1))組合為檔名,然後列印當前讀取的行輸入到檔案中,但是這種方式的檔名中日期沒有處理,所有在後面再統一對activeprocess.history目錄下面的檔案批量重新命名

注:這種方法效率很快,3.6G的資料差不多一個小時就處理完了

下面附上之後對第二種方法解析出來的檔名批量重新命名的方法:

#!/bin/sh
##批量重新命名當前資料夾activeprocess.history下的檔名
##將檔名中的"-"去掉
##
for line in `ls activeprocess.201* | awk '{print $(NF)}'`
do
    line_new=`echo $line | sed 's/-//g'`
    echo $line_new
    mv $line $line_new
done