7개의 fastQ 파일 인터리브

7개의 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 one-liner를 사용하여 7개의 파일을 생성하여 테스트되었습니다.

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

그런 다음 일부 파일을 편집하여 스크립트가 상황을 적절하게 처리할 수 있도록 동일한 수(10)의 줄을 갖지 않도록 했습니다(그렇게 했습니다. 불평 없이 다음 파일로 이동했습니다). 마찬가지로 줄 수가 4로 나누어지지 않는 입력 파일을 처리하는 데 문제가 없습니다.

참고: 이 스크립트는 메인 루프를 통해 매번 인쇄할 줄 수가 4로 하드 코딩되지 않고 명령줄의 옵션으로 표시되도록 쉽게 수정할 수 있습니다.

관련 정보