私の周りに一つあります。20pathtofiles.in
ファイルが別のフォルダーにある場合は、whichlistsという別のファイルを作成しました。道情報:
/home/users/gray_wolf/unix/File_1.tsv
/home/users/gray_wolf/unix/File_2.tsv
.
.
.
各ファイルにはおおよその内容が含まれています。11 リストについて100,000 いいね。例:
ファイル1:
Chromosome begin end .....
chr1 1000 2000
chr1 2000 3000
chr1 4000 5000
chr1 5000 6000
chr1 10000 12000
chr1 12000 13000
ファイル_2:
Chromosome begin end .....
chr1 1000 2000
chr1 4000 5000
chr1 5000 6000
chr1 6000 7000
chr1 10000 12000
chr1 13000 14000
最終必須ファイル形式:
Chromosome begin end Column5 column8
chr1 1000 2000 File1,File2,File3... File1,File2,File3...
chr1 2000 3000 File1,File2(0),File3 File1,File2(0),File3...
chr1 4000 5000 File1,File2,File3... File1,File2,File3...
chr1 5000 6000 File1,File2,File3... File1,File2,File3...
chr1 6000 7000 File1,File2,File3... File1,File2,File3...
chr1 10000 12000 File1,File2,File3... File1,File2,File3...
chr1 12000 13000 File1,File2,File3... File1,File2,File3...
chr1 13000 14000 File1(0),File2,File3... File1(0),File2,File3...
pathtofile.in
私がこれを次のように渡すとき:script.sh
./script.sh < pathtofile.in
...スクリプトは与えられたファイルを読み込み、pathtofiles.in
出力する必要があります。5- 列タブで区切られたリスト。最初サム出力列は次のようにする必要があります。サム リスト各ファイルの結合された。これ4出力列は対応する行でなければなりません。5カンマで区切られたすべての入力ファイルの列(と同じ順序pathtofiles.in
)。これ5出力列は対応する行でなければなりません。8カンマで区切られたすべての入力ファイルの列。
特定の入力行に列がない場合8、(または列5)、その位置に「(0)」を出力します。
熱を個別に切って生地/参加する機能を実行しますが、ファイルごとに行数が異なるため、順序が間違っています。どうやって使うの?アッまたは、以下で実行される他のコマンド強く打つ?
よろしくお願いします。
〜M
答え1
簡単な解決策:paste
3つのファイルをまとめて必要な列をインポートします。
paste -d' ' file1 file2 file3 |\
awk 'BEGIN { FS = " +" } { NR ==1} { printf "%-10s%-7s%-7s %-12s %-12s\n" $1,$2,$3,$6,$7 } { NR >=2 } { printf "%-10s%-7s%-7s %s,%s%s %s%s%s\n" $1,$2,$3,$6,$7,$8,$9,$10,$11 } '
これは、ファイルと出力形式のデフォルト設定に従って採用する必要があります。説明する:
1)paste -d' '
- >スペースを区切り文字として使用して、ツリーファイルを垂直方向にマージします-d
。
2)パイプで接続し、読みやすくするためにawk
新しい行にコマンドを続けます。|\
2.1) BEGIN { FS = " +" }
- 以下のすべてに対して、1 つ以上の (+) スペースをフィールド区切り文字として使用します.
2.2)最初の行に{ NR ==1}
1、2、3、6、7($1,$2 ...
)フィールドを次の形式で印刷します(二重引用符で囲む)。
%-10s
10文字の長さの文字列が修正されました(残りは空白で埋められ、左揃え)。
同じ長さの7文字の2倍、スペース2つ、12文字の長い文字列、スペースの2つ、12文字の文字列。\n
最後に新しい行を追加します。
(セクションで確認{ printf "%-10s%-7s%-7s %-12s %-12s\n" $1,$2,$3,$6,$7 }
)
2.2)データ:2行目から{ NR >=2 }
始めて列を印刷します。$1,$2,$3,$6,$7,$8,$9,$10,$11
形式は次のとおりです。%-10s%-7s%-7s %s,%s,%s %s,%s,%s\n
上記と同様ですが、たとえば、列6,7,8は任意の長さであり、カンマで区切られています。%s,%s,%s
答え2
すべての入力ファイルを同時に開くことができるプログラムが必要です。構文がawk
あるので、thatまたはperlが良い選択になります。getline <file
またはあなたが知っている他の高級言語。
そのために私はPerlを選択します。持つhttp://www.bioperl.org/遺伝子配列データファイル形式を処理するために特別に設計されたPerlモジュールを使用します。
思ったより複雑かもしれないことに気づき、途中であきらめました。入力ファイルの1つが他のファイルと異なる列の2/3値を持つ一般的なケースを処理するには、多方向diff型アルゴリズムを実行する必要があります。探している開始/終了ペアに一致するものが見つかるまで、その行を読み続けることはできません。なぜならそれが存在しないかもしれないからです。
したがって、最良の方法は、優先順位キューまたはソートされた入力を受け取ることです。各ファイルのキューに挿入された行が、現在のファイル処理を開始する前に行の後ろにあるまで読み取ります。 (または、今読んだ行がpqueueの新しい尾になるまで)。
ファイルが一度にメモリに簡単に入ることができる場合は、連想配列(column2:column3でインデックス付けされている)を使用して出力を作成すると、コーディングが簡単になります。これにより、優先順位キューは必要なく、次にどのファイルを進めるかを把握する必要もありません。
これは私のコードです。順序が間違った状況を処理したりマージしたりすることなく、入力行を繰り返します。私はこれが合理的なスタック交換の回答の範囲よりも大きいことに気づいたときに中断しましたが、これは開始を提供できます。
#!/usr/bin/perl -w
my @f = @ARGV; # list of files to process
sub getfields($) {
my $file = $_[0];
my $ln = <$file> or return (); # sentinel for EOF
my @fl = split ' ', $ln, 9;
return ( $fl[0], $fl[1], $fl[2], $fl[4], $fl[7] );
}
# open each filename in @f, storing the file handles in @f.
foreach (@f) {
open $_, '<', $_ or die "opening $_: $!";
}
my $newdata = 0;
do {
$newdata = 0;
foreach my $fd (@f) {
my @fl = getfields($fd);
next if ! (@fl); # end of file on $fd. TODO: take it out of @f?
$newdata = 1;
print join("|", @fl), "\n"; # debug
}
} while ($newdata); # done when all files are EOF