awk+uniq實現集合減法運算

tengrid發表於2009-05-18

有兩個文字A,B, 都為50w左右記錄,A包含B, 求在A中存在,在B中不存在的記錄(要求不能重複)
都有3列,格式如下,各列之間以空格分隔

uin   Ftotal   Fconsume
------------------------
11588   500     500
12398   2033    1900
13255   1000    1000
14360   1530    1210

對於DBAs 來說,最直接的方式是load to table,假設為tableA,tableB然後用下面sql求出結果集,才匯出到文字中
select distinct t1.*
  from tableA t1,tableB t2
  where t1.uin not in (select t2.uin);

但請注意,上面兩個文字都約有50w記錄,上述sql會進行 50w*50w*將比較運算才能拿到結果,效率肯定不會好到哪裡去,尤其是在輕量級的mysql等開源資料庫的情況下.

那麼是否有更加巧妙的方法實現呢?
以下是運用awk+uniq的實現

$awk '{print $2" "$3" "$1}' a.txt >a1.txt   #為了跳過前兩列進行uniq,將uin移到第三列
$awk '{print $2" "$3" "$1}' b.txt >b1.txt   #同上
$cat a1.txt b1.txt |sort -k3n|uniq -f2 -u >result.txt

這裡解釋一下第三句
sort -k3是指從第3列開始排序,n是指以numeric方式排序,而非ascii;
uniq -f2是指跳過前面2列,-u是指取不重複的行

如果b.txt中的某行在a.txt中存在,則會因為 uniq -u排除掉

 


 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/94384/viewspace-600309/,如需轉載,請註明出處,否則將追究法律責任。

相關文章