awkを使用して大容量ファイルを解析し、サブセットを抽出します。

awkを使用して大容量ファイルを解析し、サブセットを抽出します。

以下のような大きなファイルがあります。

chr10   98072   1
chr10   98073   1
chr10   98074   1
chr10   98075   2
chr10   98076   2
chr10   98077   3
chr10   98078   5
chr10   98079   5
chr11   98080   5
chr12   98081   5

各染色体には多くの項目があります。 chr10を含む行だけを抽出したいと思います。私のファイルが大きいので、このコマンドを使用してchr10行だけを抽出します。

awk '$1 ~ /^chr10$/{print}; $1 !~ /^chr10$/{exit}' cov.txt > subset.txt

awkがファイル全体を繰り返さないようにする良い方法ですか?私のファイルは染色体に従ってソートされました。

ありがとう

答え1

awk '$1=="chr10"{print; next}{exit}' cov.txt > subset.txt

テスト:/dev/null次へリダイレクト12,947,909 chr10レコードに加えて、いくつかのレコードをchr11追加chr1299,063,774行 - 出力はすべて同じです(同じmd5sum)。出力ライン数=12,947,909- 最も速いものから最も遅いものまで並べ替え:

スティーブ:awk '{ if($1 == "chr10") { print } else { exit } }' cov.txt >/dev/null

real  0m5.963s
user  0m5.896s
sys   0m0.064s

ピーターO:awk '$1=="chr10"{print; next}{exit}' cov.txt >/dev/null

real  0m6.553s
user  0m6.484s
sys   0m0.068s

コース:perl -pe '!/chr10/&&exit' cov.txt >/dev/null

real  0m8.658s
user  0m8.545s
sys   0m0.112s

スティーブ:sed -n '/^chr10[^0-9]/ { p; b; }; q' cov.txt >/dev/null

real  0m17.130s
user  0m17.077s
sys   0m0.052s

ユーザー 3138373:awk '$1 ~ /^chr10$/{print}; $1 !~ /^chr10$/{exit}' cov.txt >/dev/null

real  0m18.621s
user  0m18.541s
sys   0m0.080s

答え2

これを試してみてください。基本的なテストでは少し速いようです。正規表現の処理を避けてください。

[root@localhost tmp]# wc -l cov.txt
34970568 cov.txt
[root@localhost tmp]# time awk '$1 ~ /^chr10$/{print}; $1 !~ /^chr10$/{exit}' cov.txt > subset.txt

real    0m23.897s
user    0m22.031s
sys     0m1.556s
[root@localhost tmp]# time awk '{ if($1 == "chr10") { print } else { exit } }' cov.txt > subset.txt

real    0m16.784s
user    0m14.731s
sys     0m1.661s
[root@localhost tmp]#

また、lcd047タイミングのsedメソッドを試しました。

[root@localhost tmp]# time sed -n '/^chr10[^0-9]/ { p; b; }; q' cov.txt > subset.txt

real    0m38.343s
user    0m36.609s
sys     0m1.546s
[root@localhost tmp]#

ファイル全体を読み取っても、通常の古いgrepを使用するのが最速です。

[root@localhost tmp]# time grep "^chr10" cov.txt >subset.txt

real    0m6.546s
user    0m4.932s
sys     0m1.577s
[root@localhost tmp]#

私はgrep -Fが再び速くなると思いましたが、そうではありません。 7秒以上続きます。

[root@localhost tmp]# time grep -F chr10 cov.txt >subset.txt

real    0m7.317s
user    0m6.109s
sys     0m1.173s
[root@localhost tmp]#

答え3

より効率的に以下を実行してくださいegrep

egrep '^chr10{space or tab}' cov.txt

または、コンテンツがあなたが表示しているものと似ている場合、

grep -w chr10 cov.txt

答え4

ファイルがソートされているのであなたのコメントPerl で始まる行はchr10常にファイルの先頭にあります。

< cov.txt perl -pe '!/chr10/&&exit' > subset.txt

これにより、最初の不一致でスクリプトが終了します。

メモリに保存されている1,000,000の一致する行を持つファイルのchr10 98072 1テスト実行(空のファイルに1,000,000回の行を追加した結果)はすぐに実行されます。

~/tmp$ < cov.txt wc -l
1000000
~/tmp$ time < cov.txt perl -pe '!/chr10/&&exit' > subset.txt

real    0m0.631s
user    0m0.624s
sys 0m0.004s
~/tmp$ < subset.txt wc -l
1000000

関連情報