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
必要なすべてのファイルに4行は必要ありません。
答え1
インターリーブが何を意味するのかはわかりませんが、例のように各ファイルの最初の4行をリンクするには、その行を繰り返して次を使用しますhead
。
for f in ./File[1-7] ; do
head -n 4 "$f"
done > output.file
(類似したソースパターンを使用している場合は、出力名をFile*
指定しないでくださいFile.out
。出力名がループのglobパターンと一致する場合は、ソースファイルとして処理され、最初のファイルの行を2回取得します。)
@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にハードコードされず、コマンドラインのオプションとして表示されるように簡単に変更できます。