交错七个 fastQ 文件

交错七个 fastQ 文件

我有 7 个 FastQ 文件,我想通过以下方式将它们合并为一个:

File1 line1
File1 line2
File1 line3
File1 line4
File2 line1
File2 line2
File2 line3
File2 line4
File3 line1
File3 line2
File3 line3
File3 line4
.
.
.
File7 line1
File7 line2
File7 line3
File7 line4

我尝试过粘贴命令,但这给了我以下内容:

File1 line1
File2 line1
File3 line1
.
.
File7 line1

它并不需要我需要的每个文件中的四行。

答案1

我不确定你的交错是什么意思,但如果你只想连接每个文件的前四行,如你的示例所示,请循环它们并使用head

for f in ./File[1-7] ; do
    head -n 4 "$f"
done > output.file

(如果您使用类似File*的源模式,请不要命名输出File.out。如果输出的名称与循环中的 glob 模式匹配,它也会被视为源文件,这会让您获得第一个文件的行两次。)

正如 @steeldriver 在评论中指出的,使用 GNU coreutils 循环是不必要的,你可以这样做:

head -qn 4 ./File[1-7]

-q不是标准.)

答案2

以下perl脚本打开命令行上指定的每个文件,并将每个文件的文件句柄存储在数组中。然后,它一次从每个文件中重复读取和打印最多 4 行(每次检查 EOF,$numopen每次到达文件的 EOF 时递减计数器),直到没有文件留下未读行。

它不需要关闭文件句柄,因为perl退出时会自动关闭所有打开的文件。

#!/usr/bin/perl

use strict;

my @filehandles=();
my $files=0;

# open each input file
foreach my $filename (@ARGV) {
  open($filehandles[$files++], "<", $filename) || 
    die "Couldn't open '$filename': $!";
}

$files--;
my $numopen = $files;

# print up to 4 lines at a time from each file
while ($numopen > 0) {
  for my $i (0..$files) {
    if (!eof($filehandles[$i])) {
      for (1..4) {
        if (!eof($filehandles[$i])) {
          print scalar readline($filehandles[$i]);
        } else {
          $numopen--;
        }
      }
    }
  }
}

将此脚本保存为,例如,interleave4.pl使其可执行chmod +x interleave4.pl并运行为,./interleave4.pl File[1-7]

该脚本已通过使用以下 bash 单行代码创建 7 个文件进行了测试。

for i in {1..7}; do printf "File$i %s\n" {1..10} > "File$i"; done

然后对一些文件进行了编辑,以便它们不具有相同的行数 (10),以确保脚本能够优雅地应对这种情况(它确实如此 - 它只是毫无怨言地移至下一个文件) 。同样,它在处理行数不能被 4 整除的输入文件时也没有问题。

注意:这个脚本可以很容易地修改,这样每次通过主循环时要打印的行数不是硬编码的 4,而是作为命令行上的一个选项。

相关内容