2015-06-07 62 views
0

我有幾千萬的字符串在這樣的文本文件:排序巨大的文件數以百萬計的行

 
aa kk 
bb mm 
cc tt 
ee ff 
aa xx 
bb ss 
cc gg 
ee rr 

我想使它們看起來像:

 
aa kk,xx 
bb mm,ss 
cc tt,gg 
ee ff,rr 

我曾嘗試使用grep,sed和其他工具排序和重新排列它,但它看起來像真的很大的文件很慢的方式,即使有

LC_ALL = C grep東西

+0

如果你有一些作品,你應該包括。 –

+0

您可能想要添加一些關於規則是什麼的信息,這些信息決定了如何從「akk」到「akk,xx」排序/附加數據,以便讀者能夠爲您提供幫助。 –

回答

0

如果你要處理非常大的數據集,我建議你使用的Map Reduce pattern.For例如Hadoop框架在這裏 https://hadoop.apache.org

+2

即使這傢伙擁有100倍以上的數據,情況也會過度。 –

1

/spark.Take看看我不清楚,如果你特別希望使用標準shell工具或者不使用標準shell工具,但是Python近來在Linux上幾乎是通用的。它可以用一個相當簡單的程序來完成:

#!/usr/bin/python 

import sys 

data = { } 
while True: 
    l = sys.stdin.readline() 
    if len(l)==0: 
     break 
    a,b = l.split() 
    data.setdefault(a, [ ]).append(b) 

for k in sorted(data.keys()): 
    vs = data[k] 
    print k, ",".join(vs) 

我跑了它在5000萬線由下列C程序生成的數據,並在大約60秒我多年的老筆記本電腦完成:

#include <stdio.h> 
#include <stdlib.h> 
char letter() { return (rand() % (123-97)) + 97; } 
void main(void) 
{ 
    int i; 
    for(i=0; i<50000000; i++) 
    printf("%c%c%c %c%c%c\n", 
      letter(), letter(), letter(), 
      letter(), letter(), letter()); 
} 
+0

該解決方案比我發佈的awk版本更快。 – Cyrus

1

的性能和內存保守

sort -u YourFile | awk '{if (Last == $1) {Linked=Linked","$2} else { if (Last != "") print Last " " Linked; Last=$1;Linked=$2}} END{print Last " " Linked}' 

首先排序降低,以便讓awk將逐行讀取,而不是加載一個巨大的數組(由於您指定的行400萬)的範圍和arrance awk concatene while header與上一行相同,如果不是,則打印。對於最後一組和如果添加結束對第一線

也許有點快

sort -u YourFile | awk 'FNR==1{Last=$1;Linked=$2} FNR>1{if (Last == $1) {Linked=Linked","$2} else { print Last " " Linked; Last=$1;Linked=$2}} END{print Last " " Linked}'