在巨大的csv文件上快速grep

时间:2016-08-11 18:56:02

标签: bash grep

我有一个文件(queryids.txt),其中包含要搜索的847个关键字列表。我必须从大约12个巨大的csv文件中获取关键字(最大的有2,184,820,000行)。最终我们会将它加载到某种类型的数据库中,但就目前而言,我们只是希望某些关键字是grep&#39。

我的命令是:

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

我担心这需要很长时间。有更快的方法吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

我可以建议几点改进性能:

  1. 无需使用( .. ) &生成子shell,如果需要,您可以使用大括号{ ... } &
  2. 使用grep -F(非正则表达式或固定字符串搜索)使grep运行得更快
  3. 避免basename命令并使用bash字符串操作
  4. 试试这个脚本:

    #!/bin/bash
    
    for f in *.csv; do
        echo "Processing $f"
        filename="${f##*/}"
        LC_ALL=C grep -Ff queryids.txt "$f" > "${filename%.*}_goi.csv"
    done
    

    我建议你在较小的数据集上运行它来比较性能增益。

答案 1 :(得分: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中的值。事实上,根据您的文件包含的内容,可能会有一种非常更快,更强大的方式来执行此操作,因此,如果您编辑问题以包含文件内容的一些示例,我们可能会提供更多帮助。< / p>

我看到你现在发布了一些示例输入,实际上我们可以通过使用哈希查找更快更强大地完成这项工作:

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