2015-06-20 26 views
1

顯示列排序%完成我有大約600萬行,如下一個大管道分隔輸入的文件:提高分揀程序的效率;在終端

24|BBG000SJFVB0|EQ0000000009296012|OI SA-ADR|OIBR/C|US|ADR|Equity 16|BBG002PHVB83|EQ0000000022353186|BLOOM SELECT INCOME FUND|BLB-U|CT|Closed-End Fund|Equity 
-50|BBG000V0TN75|EQ0000000010271114|MECHEL-PREF SPON ADR|MTL/P|US|ADR|Equity 20|BBG002S0ZR60|EQ0000000022739316|DIVIDEND 15 SPLIT CORP II-RT|DF-R|CT|Closed-End Fund|Equity 
-20|BBG001R3LGM8|EQ0000000017879513|ING FLOATING RATE SENIOR LOA|ISL/U|CT|Closed-End Fund|Equity 0|BBG006M6SXL2|EQ0000000006846232|AA PLC|AA/|LN|Common Stock|Equity 

要求是如下:
1.我需要排序該輸入文件按順序依次爲第1列,第2列,然後是第2列
2.顯示例如終端/控制檯中的排序完成百分比「第2列75%排序完成」
3.最後輸出到一個單獨的文件中。

我寫下了下面的程序,完全按第1列排序。 但如何納入所有其他條件?現在還需要更多的時間來運行。有沒有更高效和更清潔的方法來做到這一點?唯一的問題是我們不能使用CPAN的任何額外外包。像使用SED/AWK的Unix解決方案是可以的,但Perl是可取的。我剛開始知道內置的Python也存在,所以解決方案也是受歡迎的。

my (%link_strength); 
{$data="datascope_input.txt"; 
$out="sort_file.txt"; 
open (my $indata , '<', $data)|| die "could not open $data :\n$!"; 
open (my $outdata , '>', $out)|| die "could not open $out :\n$!"; 
select $outdata; 
my @array=(<$indata>); 
for (@array){ 
    $link_strength{$1}=$_ if /(?:[^|]+\|){0}([^|]+)/; 
      } 
print $link_strength{$_} for (sort {$a<=>$b} keys %link_strength); 
    close ($outdata); 
    close ($indata); 
} 
+0

像這樣的http://man7.org/linux/man-pages/man1/sort.1.html這樣的系統比這個大小的數據更好地優化,而不是將整個數據集讀入perl數組。有了正確的選項,它可以很好地解決你的問題,除非沒有乾淨的方式來獲得perl或unix排序的百分比完整指標。 – Gene

+0

@Gene,我不是看起來很乾淨的方式......但任何方式如何編碼%完成指標 – pmr

+0

如何定義,然後衡量完成百分比?使用內置的排序功能可能會給您在測量作業完整性時帶來問題。 –

回答

0

從您的示例數據中,您將排序大約950MB。從普通HD(100MB/s)讀取9.5s。我不知道按照標準sort排序的速度有多快,但根據我的經驗,每個CPU核心可以記錄1-3百萬條記錄。比方說100萬。在雙核上需要3秒,而在具有更多CPU核心的服務器上需要更少。我認爲大部分時間都需要閱讀和分析數據。如此簡單

pv -p your_file.dat | sort -t'|' -k '1n,1' -k '2d,2' -k '14,14' 

應該完成大部分所需的功能。

+0

....太棒了... – pmr

2

正如我在評論說,在Linux/Unix系統排序很可能有更好的表現,但如果你真的想要的Perl,這將這樣的伎倆:

use strict; 

sub main { 
    open F, 'input.txt' or die $!; 
    my @pairs; 
    while (<F>) { 
    my @fields = split(/\|/); 
    my $key = [ @fields[0, 1, -2] ]; 
    push @pairs, [$key, $_]; 
    } 
    close F; 
    my @sorted_pairs = sort { 
    my $a_key = $a->[0]; 
    my $b_key = $b->[0]; 
    $a_key->[0] <=> $b_key->[0] 
     || $a_key->[1] cmp $b_key->[1] 
     || $a_key->[2] cmp $b_key->[2] 
    } @pairs; 
    foreach my $pair (@sorted_pairs) { 
    print $pair->[1]; 
    } 
} 

main; 

而且正如我在說評論,我知道無法自省收集進度信息。您可以通過計算髮生了多少次比較來破解某些內容,但由於您無法確定最終的數字,因此無法計算完成百分比。

+0

@ Gene..very好。我只是很好奇,「計算已經發生了多少次比較,但是因爲你永遠無法確定最終的數字」......如果我們可以指望,那麼爲什麼我們不確定這個數字? – pmr

+0

@purnendumaity:你可以知道進行了多少次比較;您可以猜測會進行多少次比較,但除了最簡單的(也是最無效的)排序之外,這可能是一個上限。在任何情況下,除非您已經編寫了類似的工具,否則您將無法確定它期望進行多少次比較。 –