Intercalar sete arquivos fastQ

0

Eu tenho 7 arquivos do FastQ e quero mesclá-los em um da seguinte maneira:

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

Eu tentei o comando colar, mas isso me dá o seguinte:

File1 line1
File2 line1
File3 line1
.
.
File7 line1

Não são necessárias quatro linhas de cada arquivo conforme necessário.

    
por Shounak Chakraborty 21.12.2017 / 13:40

2 respostas

1

Não sei ao certo o que você quer dizer com entrelaçamento, mas se quiser apenas as quatro primeiras linhas de cada arquivo concatenado, como mostra o exemplo, faça um loop sobre elas e use head :

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

(Se você usar algo como File* como o padrão de origem, não nomeie a saída File.out . Se o nome da saída corresponder ao padrão glob no loop, ele também será considerado como um arquivo de origem, você recebe as linhas do primeiro arquivo duas vezes.)

Como @steeldriver observou em um comentário, com o GNU coreutils o loop é desnecessário e você pode apenas fazer:

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

( -q não é padrão .)

    
por 21.12.2017 / 14:56
0

O seguinte script perl abre cada arquivo especificado na linha de comando, armazenando o filehandle para cada um em uma matriz. Em seguida, ele lê e imprime repetidamente até 4 linhas de cada vez de cada arquivo (verificando EOF cada vez, diminuindo um contador $numopen cada vez que atinge o EOF de um arquivo) até que não haja arquivos com linhas não lidas. / p>

Não se preocupa em fechar as alças de arquivos porque perl fecha automaticamente todos os arquivos abertos ao sair.

#!/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--;
        }
      }
    }
  }
}

Salve este script como, por exemplo, interleave4.pl , torne-o executável com chmod +x interleave4.pl e execute-o como ./interleave4.pl File[1-7]

Este script foi testado criando 7 arquivos com o seguinte one-liner bash.

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

Alguns dos arquivos foram editados para que eles não tivessem o mesmo número (10) de linhas, para garantir que o script lidaria bem com essa situação (ele simplesmente passa para o próximo arquivo sem queixa). Da mesma forma, também não há problema em lidar com arquivos de entrada com contagens de linha que não são uniformemente divisíveis por 4.

Nota: esse script pode ser facilmente modificado para que o número de linhas a serem impressas em cada passagem pelo loop principal não seja um 4, mas foi considerado como uma opção na linha de comando.

    
por 22.12.2017 / 06:42

Tags