このようなファイルがあります。
>chr1
ACGTGGC
TGCCGTT
ATCCTTG
>chr2
ACTTTTA
CTCATAA
seqを1つの文字列に変換したいです。次のように出力する必要があります。
>chr1
ACGTGGCTGCCGTTATCCTTG
>chr2
ACTTTTACTCATAA
awkを使ってどうすればよいですか?私はPerlでこれを行う方法を知っています。
ありがとう
答え1
期待どおりに動作します。
awk '/>chr/{if (x)print x;print;x="";next}{x=(!x)?$0:x$0;}END{print x;}' file
>chr1
ACGTGGCTGCCGTTATCCTTG
>chr2
ACTTTTACTCATAA
答え2
awk 'BEGIN{ RS=">[^\n]+\n"; }
NR>1{ printf( "%s", rt gensub("\n","","g") "\n" ); }
{ rt=RT; }' myfile
出力:
>chr1
ACGTGGCTGCCGTTATCCTTG
>chr2
ACTTTTACTCATAA
一般的な注意:次の入力データを使用してください。FASTA形式の例そしてそれを繰り返し81.1MBファイルをテストした結果、次のようなtime
結果が得られました。
Peter.O real 0m1.653s user 0m1.396s sys 0m0.256s
user2196728 real 0m6.587s user 0m5.972s sys 0m0.252s
kos real 0m12.866s user 0m12.589s sys 0m0.268s
結果はすべてのテスト方法でmd5sum
同じです。より一般的に機能するには、
user2196728
バージョンを変更する必要があります。>chr
>
答え3
非常に具体的なファイル形式を使用しているため、最初のレコードは常に次の形式であると仮定します><string>
。
< inputfile awk 'NR==1 {print;next} !/>/ {x=x$0;next} />/ {print x"\n"$0;x="";next} END {print x}' > outputfile
拡張:
NR==1 {
print;
next
}
!/>/ {
x=x$0;
next
}
/>/ {
print x"\n"$0;
x="";
next
}
END {
print x
}
- 最初のブロックは、現在処理中のレコード番号が1の場合にのみ実行されます。現在処理中のレコードを印刷し、次のレコードにジャンプします。
- 2番目のブロックは、正規表現が現在処理されているレコードと一致しない場合にのみ実行されます
>
。現在処理されているレコードの内容を変数にリンクx
し、次のレコードにジャンプします。 - 3番目のブロックは、正規表現が現在処理されているレコードと一致する場合にのみ実行されます
>
。変数の内容x
、改行文字、現在処理されているレコードの内容が順番に印刷され、次のレコードにジャンプします。 - 4番目のブロックは、処理するレコードがなくなったときにのみ実行されます。変数の内容を印刷します
x
。
md5sum
私はシステムの起動直後にSSDの出力ファイルを確認し、次の場所でファイルを繰り返して〜226MBのファイルを生成する次のスクリプトをsudo fstrim -v /
使用bash
してコマンドを実行した後、この質問に対するすべての答えをベンチマークしました。outputfile
このリンク100,000回:
#!/bin/bash
for ((i=0; i<3; i++)); do /usr/bin/time -f "kos\t\treal %e" awk 'NR==1 {print;next} !/>/ {x=x$0;next} />/ {print x"\n"$0;x="";next} END{print x}' outputfile > outputfile1; done
for ((i=0; i<3; i++)); do /usr/bin/time -f "Peter.O\t\treal %e" awk 'BEGIN{ RS=">[^\n]+\n"; }NR>1{ printf( "%s", rt gensub("\n","","g") "\n" ); }{ rt=RT; }' outputfile > outputfile2; done
for ((i=0; i<3; i++)); do /usr/bin/time -f "user2196728\treal %e" awk '/>/{if (x)print x;print;x="";next}{x=(!x)?$0:x$0;}END{print x;}' outputfile > outputfile3; done
md5sum outputfile1 outputfile2 outputfile3
結果は次のとおりです。
~$ sudo fstrim -v /
[sudo] password for user:
/: 68,8 GiB (73839202304 bytes) trimmed
~$ cd tmp
~/tmp$ bash exe
kos real 2.55
kos real 2.57
kos real 2.55
Peter.O real 2.93
Peter.O real 2.92
Peter.O real 2.92
user2196728 real 2.51
user2196728 real 2.51
user2196728 real 2.68
0618a8077b43eb44eb263d7d6f84777f outputfile1
0618a8077b43eb44eb263d7d6f84777f outputfile2
0618a8077b43eb44eb263d7d6f84777f outputfile3