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


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

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

  2、排序后對給定字段進行去重,去重的規則如下:

    a)排序后如果相鄰N行給定字段值相同的行數不超過兩行,則兩行都保留。

    a)排序后如果相鄰N行給定字段值相同的行數超過兩行,則保留首行和尾行。

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

  測試數據:

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腳本:

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

  給腳本添加執行權限:

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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM