根据另一个索引文件

时间:2019-01-24 11:06:08

标签: bash performance unix awk

需要使用索引文件来打印txt.gz大文件的特定行

大家好,

我找到了一些示例来打印未压缩文件的特定行,但是找不到非常大的gz文件的任何解决方案。

我的索引文件(idx.txt)如下所示,其中包含700,000个索引:

1745  
1746  
7379  
13920  
13921  
16681  
16682
...
...
...
54830241
54867703
54867710

我想在我的另一个源文件中检索所有这700,000行,这是一个非常大的压缩CSV文件,具有55,000,000行,看起来像这样:

100035243,2,"Chronic obstructive pulmonary disease","SS","LETAIRIS","AMBRISENTAN","","Dyspnoea",NA,73,"F","","","CN"
100035672,1,"Myeloproliferative disorder","PS","JAKAFI","RUXOLITINIB","ORAL","Platelet count increased",20131206,48.501,"F","79.37","KG","OT"
100035914,1,"Multiple sclerosis","PS","GILENYA","FINGOLIMOD HYDROCHLORIDE","ORAL","Lymphocyte count decreased",20130718,47.154,"F","","","OT"
....

到目前为止我尝试过的:

sed -nf idx.txt <(gzip -dc gzfile.gz) > output.txt  
awk 'NR==FNR{i[$0];next}i[FNR]' idx.txt <(gzip -dc gzfile.gz) > output.txt  

两者都很慢。
有什么想法吗?

2 个答案:

答案 0 :(得分:1)

恕我直言,您的awk代码对我来说不错,因此可以采用一种方法来提高其处理速度。尽管我不确定(并且由于您的示例不清楚,所以也没有进行测试),如果id.txt文件的最后一个条目比.gz文件中的总行数少得多,那么您实际上可以从{{1 }}代码,无需读取Input_files,只需尝试一下即可。

awk

所以我要做的是在这里创建一个名为awk 'NR==FNR{i[$0]=$0;last=$0;next} i[FNR]{print} FNR!=NR && FNR>last{exit}' idx.txt <(gzip -dc gzfile.gz) > output.txt 的变量,其值应为last的最后一行值。然后在第二种情况下,我要检查行号是否大于value ids.txt中最后一个条目的行,然后从代码退出。

编辑: :将OP的代码 ids.txt 更改为< / em> i[$0]在第一个条件下,因为条件i[$0]=$0仅在数组i具有值时才起作用。在用户在评论中提及之后对其进行了更改。

PS: 仅当您在ids.txt的最后一行值和.gz中存在的总行数之间存在巨大差异时,这肯定会节省时间文件。由于我同意您的说法,即您拥有非常庞大的数据。

答案 1 :(得分:1)

sedawk的解决方案都不错。 sed可能比awk更快。可能它们是您可以获得的更快的东西。为了减少时间,请减少输入文件的大小。

您还可以做的另一件事是在最后一行打印之后停止阅读,因此,如果您知道最后一行打印距离文件末尾很远,则可以避免冗长的解压缩:

sed -nf idx.txt <(gzip -dc gzfile.gz | head -n "$(sort -nr idx.txt | head -1)") > output.txt