如何使用shell腳本快速排序和去重文件數據

  前面寫過一篇經過shell腳本去重10G數據的文章,見《用幾條shell命令快速去重10G數據》。然而今天又碰到另一個業務,業務複雜度比上次的單純去重要複雜不少。找了好久沒有找到相應的辦法,因而用shell腳本程序去處理。具體業務邏輯:html

  一、首先根據給定指定進行排序shell

  二、排序後對給定字段進行去重,去重的規則以下:post

    a)排序後若是相鄰N行給定字段值相同的行數不超過兩行,則兩行都保留。測試

    a)排序後若是相鄰N行給定字段值相同的行數超過兩行,則保留首行和尾行。url

  就這樣一個業務邏輯,其實看起來並非太難。可是問題來了,怎麼才能在10~20G的數據中快速地進行處理呢?網上找了好久沒找到相應的處理辦法,因而先用一種相對笨的辦法實現。spa

  測試數據:code

F250A4FFIDJDJ2938X39252E7,20080304041348 ,OQQQQB8,8769E,88888626,727218105,ss
F250A4FFIDJDJ2938X39252E7,20080304041348 ,OQQQQB8,8769E,88888626,727218105,ss
F250A4FFIDJDJ2938X39252E7,20080304041348 ,OQQQQB8,8769E,88888626,727218105,ss
F250A4FFIDJDJ2938X39252E7,20080304041348 ,OQQQQB8,8769E,88888626,727218105,ss
A0223EE1IDJDJ2938X39284BE,20080304041155 ,OQQQQ54,876F0,88888120,727271202,ss
A0223EE1IDJDJ2938X39284BE,20080304041155 ,OQQQQ54,876F0,88888120,727271202,ss

  shell腳本:htm

if [ "$#" != "2" ]; then
        echo "Usage: 參數1:文件路徑,參數2:文件名。"
        exit
fi
#源文件所在目錄
filepath=$1
#源文件絕對路徑
orgfile=$filepath"/"$2
#合併字段後的臨時文件
#mergerfile="$orgfile"_merge.txt
#排序後的臨時文件
sortfile="$orgfile"_sort.txt
#最終結果文件
result_unique="$orgfile"_result_unique.txt
echo "">$result_unique
#echo "文件:$orgfile"
#echo "開始合併字段..."
#awk 'BEGIN{ FS=",";}{ print $1","$2","$3","$4","$5","$6","$7","$1$3$4 }' $orgfile > $mergerfile
#echo "字段合併結束..."

echo "文件排序 start..."
#sort -t $"," -k 1,1 -k 9,9 $mergerfile >$sortfile
sort -t $"," -k 1,2 $orgfile >$sortfile
echo "文件排序 end..."


printf "***********文件比較 start**************************\n"
echo "while read line <$sortfile"
cnt=0
#首行
firstline=""
#尾行
lastline=""
#上一次比較的key
lastKey=""
#文件行數
linecount=`sed -n '$=' $sortfile`
i=1
echo "linecount=========>>>>>>>$linecount"
while read line || [[ -n "$line" ]];
do
  echo $line;
  #合併須要比較的字段
  compare=`echo "$line"|awk -F ',' '{print $1$3$4}'`
  echo "compare=====$compare"
  #判斷字符串是否相等
  if [ "$i" != "$linecount" -a "$lastKey" = "$compare" ];then
    echo "[ = ]"
    cnt=$(expr $cnt + 1)
    lastline="$line"
  else
    #首次進來
    if [ "$firstline" = "" ];then
        firstline=$line
        cnt=1
        #echo "$firstline" >> $result_unique
    fi
    #echo "----$i---------------->>>>>>>>>>>$cnt"
    if [ $cnt -gt 1 -o "$i" == "$linecount" ];then
        echo "----$i---------------->>>>>>>>>>>$cnt"

        if [ "$i" != "$linecount" -a "$lastline" != "" ];then
                echo "$lastline" >> $result_unique
                echo "$line" >> $result_unique
        fi

        # 最後一行的特殊處理
        if [ "$i" == "$linecount" ];then
                echo "================last line==================="
                echo "$line" >> $result_unique
        fi

        firstline="$line"
        lastline="$line"
        cnt=1
    elif [ $cnt -eq 1 ];then
        firstline=$line
        lastline="$line"
        cnt=1
        echo "$lastline" >> $result_unique
    fi
  fi
  # 對比key
  lastKey="$compare"
  let i++
done <$sortfile

echo "*******************文件 $orgfile 處理結束***************************"
echo "*******************結果文件 $result_unique ***************************"
exit

  給腳本添加執行權限:blog

chmod +x uniquefile.sh

  執行shell腳本排序

sh ./uniquefile.sh ./文件路徑 文件名

  結果:

[root@xddsdsdsddssd ~]# sh uniquefile.sh ./ testfile.csv 
文件排序 start...
文件排序 end...
***********文件比較 start**************************
while read line <.//testfile.csv_sort.txt
linecount=========>>>>>>>6
A0223EE1IDJDJ2938X39284BE,20080304041155 ,OQQQQ54,876F0,88888120,727271202,ss
compare=====A0223EE1IDJDJ2938X39284BEOQQQQ54876F0
A0223EE1IDJDJ2938X39284BE,20080304041155 ,OQQQQ54,876F0,88888120,727271202,ss
compare=====A0223EE1IDJDJ2938X39284BEOQQQQ54876F0
[ = ]
F250A4FFIDJDJ2938X39252E7,20080304041348 ,OQQQQB8,8769E,88888626,727218105,ss
compare=====F250A4FFIDJDJ2938X39252E7OQQQQB88769E
----3---------------->>>>>>>>>>>2
F250A4FFIDJDJ2938X39252E7,20080304041348 ,OQQQQB8,8769E,88888626,727218105,ss
compare=====F250A4FFIDJDJ2938X39252E7OQQQQB88769E
[ = ]
F250A4FFIDJDJ2938X39252E7,20080304041348 ,OQQQQB8,8769E,88888626,727218105,ss
compare=====F250A4FFIDJDJ2938X39252E7OQQQQB88769E
[ = ]
F250A4FFIDJDJ2938X39252E7,20080304041348 ,OQQQQB8,8769E,88888626,727218105,ss
compare=====F250A4FFIDJDJ2938X39252E7OQQQQB88769E
----6---------------->>>>>>>>>>>3
================last line===================
*******************文件 .//testfile.csv 處理結束***************************
*******************結果文件 .//testfile.csv_result_unique.txt ***************************

  最終結果文件:

[root@wewewwew ~]# more testfile.csv_result_unique.txt 

A0223EE1IDJDJ2938X39284BE,20080304041155 ,OQQQQ54,876F0,88888120,727271202,ss
A0223EE1IDJDJ2938X39284BE,20080304041155 ,OQQQQ54,876F0,88888120,727271202,ss
F250A4FFIDJDJ2938X39252E7,20080304041348 ,OQQQQB8,8769E,88888626,727218105,ss
F250A4FFIDJDJ2938X39252E7,20080304041348 ,OQQQQB8,8769E,88888626,727218105,ss

  時間比較趕,先這樣實現吧。哪位親們有好的辦法請告訴我。

相關文章
相關標籤/搜索