
2つのファイルがあります。最初のものはfileA
次のとおりです。
TCONS_00000066 XLOC_000030 - u q1:XLOC_000030|TCONS_00000066|0|0.000000|0.000000|0.000000|0.000000|-
TCONS_00000130 XLOC_000057 - u q1:XLOC_000057|TCONS_00000130|0|0.000000|0.000000|0.000000|0.000000|-
TCONS_00000395 XLOC_000206 - u q1:XLOC_000204|TCONS_00000393|0|0.000000|0.000000|0.000000|0.000000|-
FileB
良い:
>TCONS_00000001 gene=XLOC_000001
AGATGAGCTGGTGGGGATGCTCTAAGAGAACGAGAGAAGCACAGAGCAGATAAACCACACCCACAGGCAC
CACCGTCCTTGTTGGTAATGAAGAAGACGAGACGACGACTTCCCCACTAGGAAACACGACGGAGGCGGAG
ATGATCGACGGCGGAGAGAGCTACAGAAACATCGATGCCTCCTGTCCAATCCCCCCATCCCATTCGGTAG
TTGGATTGAAGACTACCGAATAAGAGAAGCAGGCAGGCAGACAAACCCTTGAACCAAGGAGTCCTCGCTG
AGGAAGCTTTGGATCCACGACGCAGCTATGGCCTCCCCGCCCACCAGGCCGCCAGCCACAACCAGCTGAC
TAGGTCGCATGCATCATCAGATTTCAATCTCCCTTCGTTCCCTGTCCCTAATCCAATACCAATAGGGAGC
AATCAGCTGCTCCTCGACGGCGAGGGAGATGTCGTCGGCCGCGGGCCAAGACAACGGAGATACCGCTGGG
GACTACATCAAGTGGATGTGCGGCGCCGGTGGCCGTGCGGGCGGCGCCATGGCCAACCTCCAGCGCGGCG
TTGGCTCCCTCGTCCGTGACATTGGCGACCCCTGCCTCAACCCATCCCCCGTTAAGGGGAGCAAAATGCT
CAAACCGGAAAAATGGCACACATGTTTTGATAATGATGGAAAGGTCATAGGTTTCCGTAAAGCCCTAAAA
TTCATTGTCTTAGGGGGTGTGGATCCCACTATTCGAGCTGAAGTTTGGGAATTTCTTCTTGGCTGCTATG
CCTTGAGTAGTACCTCAGAGTATAGGAGGAAACTAAGAGCTGTTAGAAGGGAAAAATATCAAATTTTAGT
TAGACAGTGCCAGAGCATGCACCCAAGCATTGGTACAGGTGAGCTTGCTTACGCTGTTGGATCAAAGCTA
最初の列には、fileA
選択した成績表番号とfileB
すべての成績表の順序が含まれます。fileB
最初の列をスキャンしfileA
、成績表番号と一致する成績表の末尾のシーケンスを印刷したいと思います。
答え1
sed -n 's|^\(TCONS_[0-9]*\) .*|\
/^>\1 /,/\\n>/P|p' fileA |
sed -e '$!N' -f - -e D fileB >outfile
...これはあなたが望むものを達成します。TCONS_
文字列と空白文字で始まる fileA の各行について、最初の行はsed
次の行を出力します。
/^>TCONS_000001 /,/\n>/P
…000001
線を生成する一連の数字はどこにありますか?
2番目はsed
3つのスクリプトを提供します。すべてが対応する入力ファイルfileBに適用されます。
最初のコマンドは、最後の行を除くパターン空間のすべての行にext入力行を追加するように
$!N
指示します。N
!
$
以下はstdinです。前述したように、これのために作成された
-f -
最初の項目です。sed
- 最初は2番目の行ごと
sed
に2つのアドレス範囲を印刷し、2番目は//,//
パターンスペースの2つのアドレス間のすべての行に最初のewlineをsed
印刷するように指示します。P
\n
- 最初は2番目の行ごと
最後のスクリプトは、単にパターンスペースに最初に表示されるewlineを削除し、3つのスクリプトをすべて再試行するように指示
D
します。sed
D
\n
その結果、sed
ブロックヘッダーがパターンスペースの先頭にあるとき、2番目のスクリプトの最初のスクリプトと一致するすべての範囲が開始されます。 extにそれをプルし、^
前の行以降の反復を削除し、次の行から始まります。閉じるブロックヘッダーが最初に表示され、まだewline文字で区切られたパターンスペースの後ろにあります。 2番目のものは対応する区切り文字よりも印刷されないため、fileBを1行前に移動して、fileAの列1の文字列で始まるすべてのブロックを印刷し、他のものは印刷しません。N
D
\n
sed
P
sed
その他(より複雑で/より効率的)方法
洗練:
also_fasta()( IFS='
'; get_match_lines(){
tr -s '[:space:]' \\n |
grep "$1" | grep -nFf - "$3"
}
get_script(){
set \\ '\1,$p;n\' '1,\1b\1\' \
'/^>/!b\1|p' '$c\' q
sed -n "s|\([^:]*\).*|:\1$*"
}
get_match_lines "$@" < "$2" |
get_script | sed -nf - "$3"
)
シェルで関数を定義し、次のように呼び出すと:
also_fasta 'TCONS_[0-9]*' fileA fileB
…もう効果があると思います。
私はいくつかのテストを行った後、これを見つけました。最初は確かに動作しますが。遅い大きな入力の場合。
例のすべての行を[ACGT]*
クリップボードにコピーし、次のサンプルデータを作成しました。
seq -w -s " gene=XLOC_dummy
$( xsel -bo | sed 's/ *$//')
>TCONS_" 0 512 99999999 >/tmp/temp
seq
上記は、次のブロックを作成するために使用されます。
>TCONS_99993600 gene=XLOC_dummy
AGATGAGCTGGTGGGGATGCTCTAAGAGAACGAGAGAAGCACAGAGCAGATAAACCACACCCACAGGCAC
CACCGTCCTTGTTGGTAATGAAGAAGACGAGACGACGACTTCCCCACTAGGAAACACGACGGAGGCGGAG
ATGATCGACGGCGGAGAGAGCTACAGAAACATCGATGCCTCCTGTCCAATCCCCCCATCCCATTCGGTAG
TTGGATTGAAGACTACCGAATAAGAGAAGCAGGCAGGCAGACAAACCCTTGAACCAAGGAGTCCTCGCTG
AGGAAGCTTTGGATCCACGACGCAGCTATGGCCTCCCCGCCCACCAGGCCGCCAGCCACAACCAGCTGAC
TAGGTCGCATGCATCATCAGATTTCAATCTCCCTTCGTTCCCTGTCCCTAATCCAATACCAATAGGGAGC
AATCAGCTGCTCCTCGACGGCGAGGGAGATGTCGTCGGCCGCGGGCCAAGACAACGGAGATACCGCTGGG
GACTACATCAAGTGGATGTGCGGCGCCGGTGGCCGTGCGGGCGGCGCCATGGCCAACCTCCAGCGCGGCG
TTGGCTCCCTCGTCCGTGACATTGGCGACCCCTGCCTCAACCCATCCCCCGTTAAGGGGAGCAAAATGCT
CAAACCGGAAAAATGGCACACATGTTTTGATAATGATGGAAAGGTCATAGGTTTCCGTAAAGCCCTAAAA
TTCATTGTCTTAGGGGGTGTGGATCCCACTATTCGAGCTGAAGTTTGGGAATTTCTTCTTGGCTGCTATG
CCTTGAGTAGTACCTCAGAGTATAGGAGGAAACTAAGAGCTGTTAGAAGGGAAAAATATCAAATTTTAGT
TAGACAGTGCCAGAGCATGCACCCAAGCATTGGTACAGGTGAGCTTGCTTACGCTGTTGGATCAAAGCTA
/tmp/temp
...文字列の数値部分が>TCONS_[0-9]*
ブロックごとに512間隔で増加するファイル。全体のファイルサイズは約185mbsです。00000512
99999999
それから私は次のことをしました。
grep -F 00\ </tmp/temp | cut -d\> -f2 >/tmp/tempA
...スキーマファイル用(これは一致TCONS_[0-9]*00<space>
する項目に選択範囲を絞り込みます。)。
2つのファイルの行数は次のとおりです。
wc -l /tmp/temp*
2734369 /tmp/temp
7813 /tmp/tempA
2742182 total
そのサイズの入力に対しても2つのsを実行しませんでしたが、sed
私が試した最大の提案は、sed | sed
データファイル、そのサイズの什分の一、および選択したスキーマファイルです。2\
しかし、それに似ています。
とにかく、何が起こっているのかを考えてみると、パターンファイルが8000個の正規表現に近づくにつれて、1行が来るたびに引き続き現れる前の正規D
表現をすべてチェックして動作する必要があることに気づきました。これはおそらくいいえ頑張りました。
少なくとも私が生成する入力には私に合ったものがあります。それはやや連続しています。そのスレッドに従い、正規表現の代わりに行番号で作業できる場合は、連続する必要もないことに気づきましたgrep
。だから。
私が実行したコマンド(そして上記機能の基礎)例:
sed -n 's|^\(TCONS_[0-9]*\) .*|>\1 |p
' < /tmp/tempA |
grep -nFf - /tmp/temp |
sed -n 's|\([^:]*\):.*|:\1\
\1,$p;n;1,\1b\1\
/^>/!b\1|p;$c\' -e q |
sed -nf - /tmp/temp
これを使用する場合は、fileB
for/tmp/temp
とfileA
forを交換する必要があります/tmp/tempA
。
grep -F
正規表現の代わりに固定文字列を使用すると、はるかに高速です。(特に私たちが一次競争会社と協力していることを考慮すると)- 残りは、デフォルトでgrep
各結果の先頭に返される行番号を除くすべての結果を無視します。sed
途中の内容は、最終的にデータファイルを処理するプログラムが一度でもスクリプトを逆追跡しないように出力を処理します。入力処理中にスクリプトファイルを処理しますgrep
。sed
印刷された各行の終わりには、sed
次のような内容が記録されます。sed
grep
:2732801 #define branch label :LINENO
2732801,$p #if LINENO thru last line print
n #overwrite current line w/ next line
1,2732801b2732801 #if first line thru LINENO branch to :LINENO
/^>/!b2732801 #if !not /^>/ branch to :LINENO
したがって、各一致grep
に対してsed
2つの小さな読み取りループが実装されます。 1つ目は、sed
現在の行番号が増加する次grep
の一致が出るまで、現在の行を次の行で上書きするランダムな動作です。 2番目は、sed
現在の行が印刷され続け、次の行が一致するまで次の行で上書きされる印刷ループです/^>/
。このようにして、sed
スクリプトはその中のファイルと同期して処理されます。つまり、次の一致する行番号に許可されている以上のスクリプトを進めません。
これは他のスクリプトよりはるかに優れています。それは185mbsを扱う...
( also_fasta 'TCONS_[0-9]*' /tmp/tempA /tmp/temp; ) \
3.93s user 0.39s system 100% cpu 4.281 total
...もう1つは入力サイズの10%を処理します...
( sed -n 's|^\(TCONS_[0-9]*\) .*|/>\1 /,/\\n>/P|p' /tmp/tempA |sed -e -f... ) \
108.58s user 0.04s system 100% cpu 1:48.56 total
具体的には、他のスクリプトの入力行数は次のとおりです。
wc -l /tmp/temp*
273435 /tmp/temp
782 /tmp/tempA
274217 total
答え2
この種の作業を頻繁に実行する予定の場合は、この種の作業に本当に役立ついくつかのツールを使用することをお勧めします。
FastaToTbl
:#! /bin/sh gawk '{ if (substr($1,1,1)==">") if (NR>1) printf "\n%s\t", substr($0,2,length($0)-1) else printf "%s\t", substr($0,2,length($0)-1) else printf "%s", $0 }END{printf "\n"}' "$@"
ファイルを
FastaToTbl
inとして保存~/bin
して実行可能にしますchmod 755 ~/bin/FastaToTbl
。TblToFasta
#! /bin/sh gawk '{ sequence=$NF ls = length(sequence) is = 1 fld = 1 while (fld < NF) { if (fld == 1){printf ">"} printf "%s " , $fld if (fld == NF-1) { printf "\n" } fld = fld+1 } while (is <= ls) { printf "%s\n", substr(sequence,is,60) is=is+60 } }' "$@"
ファイルを
TblToFasta
inとして保存~/bin
して実行可能にしますchmod 755 ~/bin/TblToFasta
。
これで、これら2つのスクリプトが設定されているので、FastaToTbl
FASTAシーケンスをTbl形式(配列名、TAB、シーケンス)に変更して、次の方法で簡単に検索できます。
FastaToTbl fileB | grep -f <(awk '{print $1}' fileA) | TblToFasta
スクリプトを使用して、FastaToTbl
シーケンスとIDを同じファイルに入れます。検索するパターンファイルを要求する「file」としてgrepに渡すことができるオプションを使用しているので、のawk '{print $1}' fileA
最初のフィールドを印刷します。最後にFASTA形式に戻ります。fileA
<()
-f
TblToFasta
最後に、私の情報を確認してください。retrieveseqs.pl
スクリプトはこの操作と他の多くの操作を実行できます。たとえば、この場合は次のことができます。
retrieveseqs.pl -f fileB fileA
1この2つのスクリプトを最初に書いたJF Abrilに感謝します。