并行拆分 Fasta 文件

Split Fasta file with parallel

我有一个很长的 Fasta 文件(来自经过处理的 Fastq 文件),我需要将其拆分成更小的文件。我正在尝试使用并行来做到这一点,但我不确定如何去做。我需要将 Fasta 文件拆分成更小的文件,每个文件的最大大小为 700Mb。我的目标是将每个文件保存为 {n}.faa,其中包含 n 的序号(01.faa、02.faa、03.faa、04.faa ... 10.faa, 11.faa, 12.faa ... n.faa), 每个都具有大致相同的大小。据我了解并行,我认为这是我应该使用的:

parallel -a MyFile.fasta --block 700M --pipe-part --recend '\n' --recstart '>' {} > #.faa

不过我有两个问题。首先,如何使每个文件的大小大致相同,以便对于 1500Mb 的初始文件,我不会以两个 700Mb 文件和一个 100Mb 文件结束,而是三个 500Mb 文件?我对此的一个想法是计算所需文件的数量(原始文件大小 / 700,四舍五入),然后将原始大小除以所需文件的数量,并且由于该数字已四舍五入为整数,我有块大小(小于 700Mb),所以我会做这样的事情:

original_size=$(wc -c MyFile.fasta | sed 's/ .*//')  #get size
number=`expr $original_size / 734003200 + 1`
size=`expr $(wc -c MyFile.fasta) / $number`

有了这个我可以得到每个文件应该有的大小(以字节为单位),得到大小相同但都在 700Mb 以下的文件。有没有更简单的方法只使用并行工具来做到这一点?

我应该怎么做才能将每​​个块保存在不同的文件中? “{} > #.faa”方法是否正确?或者使用 --cat 会更有效率吗? 另外,如何让数字“#”分别为两位数 (01...10)?

此外,如果它必须将文件拆分为 12 个较小的文件,但我的计算机只有 8 个内核,它是否会使用 8 个内核来处理 8 个文件并在完成作业时 运行 剩下的 4 个作业,或者我应该以某种方式将我的工作限制在核心数量上吗?

这将拆分为大约 700 MB 的文件(+- 单个记录的大小)。它们将被命名为 1..n:

parallel -a MyFile.fasta --block 700M --pipe-part --recend '\n' --recstart '>' "cat >{#}"

您不能轻易要求 GNU Parallel 将 1500 MB 变成 3x500 MB 而不是 2x700 MB + 1x100MB。

但是您可以让 GNU Parallel 将文件拆分为每个作业槽给定数量的文件。每个作业槽一个文件:

parallel -a MyFile.fasta --block -1 --pipe-part --recend '\n' --recstart '>' "cat >{#}"

每个作业槽两个文件:

parallel -a MyFile.fasta --block -2 --pipe-part --recend '\n' --recstart '>' "cat >{#}"

作业槽数由 -j 给出,默认为 CPU 个核心数。

要使名称成为 01..n,您必须用零填充它们。 GNU Parallel 不提供开箱即用的功能,但在 --rpl 部分的手册页中,您将获得一个示例,说明如何定义替换字符串来做到这一点:

--rpl '{0#} $f=1+int("".(log(total_jobs())/log(10)));  $_=sprintf("%0${f}d",seq())'

所以:

parallel -a MyFile.fasta --block 700M --pipe-part --recend '\n' --recstart '>' \
  --rpl '{0#} $f=1+int("".(log(total_jobs())/log(10)));  $_=sprintf("%0${f}d",seq())' \
  "cat >{0#}"

如果你经常使用{0#},你可以简单地将--rpl定义放在~/.parallel/config.