2016-08-11 124 views
1

我有一個文件(queryids.txt)與847個關鍵字列表進行搜索。我必須從大約12個巨大的csv文件(最大的有2,184,820,000行)grep關鍵字。最終我們會將它加載到某種數據庫中,但現在我們只希望某些關鍵字被grep化。快速grep在巨大的csv文件

我的命令是:

LC_ALL=C fgrep -f queryids.txt subject.csv 

我想到寫一個bash腳本這樣的:

#!/bin/bash 

for f in *.csv 
do 
    (echo "Processing $f" 
    filename=$(basename "$f") 
    filename="${filename%.*}" 
    LC_ALL=C fgrep -f queryids.txt $f > $filename"_goi.csv") & 
done 

,我將使用運行它:nohup bash myscript.sh &

的queryids.txt外觀像這樣:

ENST00000401850 
ENST00000249005 
ENST00000381278 
ENST00000483026 
ENST00000465765 
ENST00000269080 
ENST00000586539 
ENST00000588458 
ENST00000586292 
ENST00000591459 

主題文件看起來是這樣的:

target_id,length,eff_length,est_counts,tpm,id 
ENST00000619216.1,68,2.65769E1,0.5,0.300188,00065a62-5e18-4223-a884-12fca053a109 
ENST00000473358.1,712,5.39477E2,8.26564,0.244474,00065a62-5e18-4223-a884-12fca053a109 
ENST00000469289.1,535,3.62675E2,4.82917,0.212463,00065a62-5e18-4223-a884-12fca053a109 
ENST00000607096.1,138,1.92013E1,0,0,00065a62-5e18-4223-a884-12fca053a109 
ENST00000417324.1,1187,1.01447E3,0,0,00065a62-5e18-4223-a884-12fca053a109 

我而言,這將花費很長的時間。有沒有更快的方法來做到這一點?

謝謝!

+0

大部分時間取讀CSV文件。無論你如何構建循環,都必須完成,而且你不能更快地完成任務。 'queryids.txt'很小,所以重新閱讀每個文件都不會有什麼重大區別。 – Barmar

+0

只是爲了完成這個問題 - 請編輯它以包含您發佈的2個輸入文件的預期輸出。 –

+1

你有一個包含兩個_billion_行的CSV文件?_「最終我們會把它加載到某種類型的數據庫中,但現在呢」_讓我猜,你每年都會這樣說十年? :)退出餵養你的技術債務! –

回答

2

幾件事我可以建議以提高性能:

  1. 無需產卵使用(..) &一個子shell,您可以根據需要使用大括號{ ... } &
  2. 使用grep -F(非正則表達式或固定字符串搜索)使grep的運行速度
  3. 避免basename命令,並使用bash字符串操作

試試這個腳本:

​​

我建議你在較小的數據集上運行此操作以比較性能增益。

+1

'fgrep'類似於'grep -F',前者被棄用而後者被棄用。 – heemayl

+0

是的,我忽略了在OP腳本中使用'fgrep'。 – anubhava

+0

謝謝,我會嘗試。我還添加了有關這些文件的詳細信息以提供更多的上下文。 –

0

你可以代替試試這個:

awk ' 
BEGIN { 
    while ((getline line < "queryids.txt") > 0 ) { 
     re = (re=="" ? "" : re "|") line 
    } 
} 
FNR==1 { close(out); out=FILENAME; sub(/\.[^.]+$/,"_goi&",out) } 
$0 ~ re { print > out } 
' *.csv 

它使用正則表達式,而不是字符串比較 - 不論該問題,如果是這樣,我們可以做些什麼取決於queryids.txt值。事實上,根據你的文件包含的內容,可能會有更快,更穩健的方式來實現這一點,所以如果你編輯你的問題來包含文件內容的一些例子,我們可以提供更多的幫助。

我看你現在已經發布了一些樣品輸入而事實上,我們可以通過使用哈希查找做到這一點更快,更有力:

awk ' 
BEGIN { 
    FS="." 
    while ((getline line < "queryids.txt") > 0 ) { 
     ids[line] 
    } 
} 
FNR==1 { close(out); out=FILENAME; sub(/\.[^.]+$/,"_goi&",out) } 
$1 in ids { print > out } 
' *.csv 
+0

我已經添加了關於這些文件的詳細信息以提供更多的上下文。 –

+0

我已經更新了我的答案,以顯示最後更快的方法。 –

+0

如果'grep -f'沒有在內部執行這個操作,事實上會更快,我會感到驚訝。 'grep'已經很好的優化了。如果在'awk'中逐行掃描文件比'grep'自己的搜索更快,我會非常驚訝。 – chepner