有效连接> 100个文件

时间:2019-01-03 08:52:04

标签: bash performance join merge

我有一个列表,其中包含> 100个制表符分隔的文件,包含5-8百万行和16列(始终以完全相同的顺序)。我需要从每个文件中提取5个特定的列,包括一个标识符列。我的最终输出(以3个输入文件为例)应该是4个文件,其中包含以下列:

  • 输出1:ID,VAR1
  • 输出2:VAR2.1,VAR2.2,VAR2.3
  • 输出3:VAR3.1,VAR3.2,VAR3.3
  • 输出4:VAR4.1,VAR4.2,VAR4.3

其中“ .1”,“。2”和“ .3”表示该列分别来自第一个,第二个和第三个输入文件。

我的问题是输入文件包含部分重叠的ID,我需要提取这些行的并集(即,在一个输入文件中至少出现一次的所有ID)。更确切地说,output1应该包含所有输入文件的“ ID”和“ VAR1”列的并集。其余输出文件的行顺序应与output1相同。最后,在任何给定的输入文件中不存在的行应在output2,output3和output4中填充“ NA”。

我使用while循环,awk和join的组合来完成工作,但是要花很多时间。我想知道是否有一种更快的方法来完成此操作,因为我必须在不同的输入文件中反复运行相同的脚本。

到目前为止,我的脚本是

cat

最后的备注:我对输出1使用{{1}},因为在所有输入文件中,VAR1中具有相同ID的所有值都是相同的(我在预处理文件时已经确定了这一点)。因此,我可以将尚未包含的行追加到output1的底部,并对最终的输出文件进行排序

1 个答案:

答案 0 :(得分:1)

首先,您必须弄清楚大部分时间在哪里丢失。您可以回显“运行X”;时间。/ X`,并确保您没有尝试优化脚本的最快部分。

您可以简单地在后台(cmd args ) &中并行运行三个联接,然后在wait中并行运行三个联接。如果这需要1秒钟,而awk之前需要10分钟,那么这将无济于事。

您还可以将wait放在cat output 1 tmp5...之前和最后sort -k1...行之前。为此,您必须使用不同的方式命名临时文件,并在join之前重命名它们。这个想法是为后台第一个文件wait生成三个并行联接的输入,然后重命名文件,在后台运行join s并生成下一个输入。循环完成后,只需等待最后join秒即可完成。如果awk所消耗的时间与join的CPU时间相当,这将有所帮助。

HTH,您可以创建更复杂的并行执行方案。