次の構造のファイルがあります。
>Cluster 0
0 51aa, >MG00HS05:520:C8M1TACXX:3:1101:1428:2080/1... *
1 51aa, >MG00HS05:520:C8M1TACXX:3:1101:1658:2480/1... at 3:51:1:49/96.08%
2 51aa, >MG00HS05:520:C8M1TACXX:3:1101:15131:2756/1... at 1:51:1:51/100.00%
[thousands of similarly looking lines]
>Cluster 1
0 51aa, >MG00HS05:520:C8M1TACXX:3:1101:3733:2088/1... *
1 50aa, >MG00HS05:520:C8M1TACXX:3:1101:6962:2026/1... at 2:50:1:49/98.00%
2 51aa, >MG00HS05:520:C8M1TACXX:3:1101:14617:2071/1... at 2:51:1:50/96.08%
[thousands of similarly looking lines]
>Cluster 2
0 51aa, >MG00HS05:520:C8M1TACXX:3:1101:5164:2153/1... *
1 51aa, >MG00HS05:520:C8M1TACXX:3:1101:15660:20057/1... at 1:51:1:51/98.04%
2 51aa, >MG00HS05:520:C8M1TACXX:3:1101:8563:35493/1... at 1:50:1:51/96.08%
[thousands of similarly looking lines]
で始まる行数は>
約200万減ります。
>
次の行を抽出せずに開始する行とその後の行を抽出して>
ファイルに入れたいと思います。このような:
ファイル1:
>Cluster 0
0 51aa, >MG00HS05:520:C8M1TACXX:3:1101:1428:2080/1... *
1 51aa, >MG00HS05:520:C8M1TACXX:3:1101:1658:2480/1... at 3:51:1:49/96.08%
2 51aa, >MG00HS05:520:C8M1TACXX:3:1101:15131:2756/1... at 1:51:1:51/100.00%
[thousands of similarly looking lines]
文書2
>Cluster 1
0 51aa, >MG00HS05:520:C8M1TACXX:3:1101:3733:2088/1... *
1 50aa, >MG00HS05:520:C8M1TACXX:3:1101:6962:2026/1... at 2:50:1:49/98.00%
2 51aa, >MG00HS05:520:C8M1TACXX:3:1101:14617:2071/1... at 2:51:1:50/96.08%
[thousands of similarly looking lines]
ファイル_3
>Cluster 2
0 51aa, >MG00HS05:520:C8M1TACXX:3:1101:5164:2153/1... *
1 51aa, >MG00HS05:520:C8M1TACXX:3:1101:15660:20057/1... at 1:51:1:51/98.04%
2 51aa, >MG00HS05:520:C8M1TACXX:3:1101:8563:35493/1... at 1:50:1:51/96.08%
[thousands of similarly looking lines]
Bashでこれを行うようになっているスクリプトを作成しましたが、うまくいきませんでした。私はbashスクリプトの専門家ではありません。
mkdir FemaleMito1_clusters
while read i
do $i > FemaleMito1_clusters/FemaleMito1_${i#>}
n=1
while [ `grep -A $n $i FemaleMito1_cdhit2 | tail -n1 | grep -c "^>"` -eq 0 ]
do grep -A"$n" $i FemaleMito1_cdhit2 | tail -n1 >> FemaleMito1_clusters/FemaleMito1_"${i#>}"
((n++))
done
done < FemaleMito1_cdhit2_list #this is a file containing just the lines starting with >
どうすればいいですか?私のスクリプトを完全にスキップできます。私が望むことをする行があるかもしれません。
また、ファイルをフィルタリングし、特定の行番号の上にあるファイルのみを保持する必要があります。ファイルを生成した後簡単にできる方法を考えてみましたが、wc -l
無駄なファイルを生成せずに命令に含めることができる方法があればいいようです。
答え1
awkではこれを簡単に行うことができます。
awk '{ if(/^>/){name=$0; sub(/^>/,"", name);}{print >> name".fa"}}' file.fa
これは入力ファイルのすべての行を繰り返し、最初の文字がこの場合は行をとして>
保存します。次に、ファイル名にその内容を望まないので、から内容を削除name
します。最後に、各行は現在のシーケンスの名前が何であれ、whereというファイルに追加されます。>
name
name.fa
name
N行より長いシーケンスのみを印刷するには、次のものを使用できます。
awk -v min=4 '{
if(/^>/){
if(num >= min){
print seq >> name".fa"
}
name=$0;
sub(/^>/,"", name);
seq=$0;
num=0
}
else{
seq = seq"\n"$0;
num++
}
}
END{
if(num >= min){
print seq >> name".fa"
}
}' file.fa
基本原則として、テキスト処理にシェルループを使用しないでください。ゆっくりと這い、エラーが発生しやすい。
答え2
(あなたの意見で提案されているように)あなたのアプリケーションにもっと適したバイオインフォマティクスツールがあるかもしれませんが、あなたはそれを使って行うことができますcsplit
。
csplit -sz file '/^>/' '{*}'
与えられた
$ head xx*
==> xx00 <==
>Number_one
[some thousands lines]
==> xx01 <==
>Number_two
[some other thousands lines, less than the latter]
==> xx02 <==
>Number_three
[Some other hundreds lines]
出力ファイル名の番号付けと書式設定のオプションについては、マニュアルページ(man csplit
)を参照してください。