ファイルaの最初の列をファイルbの段落と一致させます。

ファイルaの最初の列をファイルbの段落と一致させます。

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番目はsed3つのスクリプトを提供します。すべてが対応する入力ファイルfileBに適用されます。

  1. 最初のコマンドは、最後の行を除くパターン空間のすべての行にext入力行を追加するように$!N指示します。N!$

  2. 以下はstdinです。前述したように、これのために作成された-f -最初の項目です。sed

    • 最初は2番目の行ごとsedに2つのアドレス範囲を印刷し、2番目は//,//パターンスペースの2つのアドレス間のすべての行に最初のewlineをsed印刷するように指示します。P\n
  3. 最後のスクリプトは、単にパターンスペースに最初に表示されるewlineを削除し、3つのスクリプトをすべて再試行するように指示Dします。sedD\n

その結果、sedブロックヘッダーがパターンスペースの先頭にあるとき、2番目のスクリプトの最初のスクリプトと一致するすべての範囲が開始されます。 extにそれをプルし、^前の行以降の反復を削除し、次の行から始まります。閉じるブロックヘッダーが最初に表示され、まだewline文字で区切られたパターンスペースの後ろにあります。 2番目のものは対応する区切り文字よりも印刷されないため、fileBを1行前に移動して、fileAの列1の文字列で始まるすべてのブロックを印刷し、他のものは印刷しません。ND\nsedPsed


その他(より複雑で/より効率的)方法


洗練:

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です。0000051299999999

それから私は次のことをしました。

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

これを使用する場合は、fileBfor/tmp/tempfileAforを交換する必要があります/tmp/tempA

grep -F正規表現の代わりに固定文字列を使用すると、はるかに高速です。(特に私たちが一次競争会社と協力していることを考慮すると)- 残りは、デフォルトでgrep各結果の先頭に返される行番号を除くすべての結果を無視します。sed途中の内容は、最終的にデータファイルを処理するプログラムが一度でもスクリプトを逆追跡しないように出力を処理します。入力処理中にスクリプトファイルを処理しますgrepsed

印刷された各行の終わりには、sed次のような内容が記録されます。sedgrep

: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に対してsed2つの小さな読み取りループが実装されます。 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

おすすめ記事