文字列の特定の開始から終了まで、一致の前後のテキストを印刷します。

文字列の特定の開始から終了まで、一致の前後のテキストを印刷します。

何千ものアイテムを含む大規模なGenbankファイルからアイテムを抽出しようとしています。検索文字列には固有の遺伝子名を使用しましたが、非常に効果的でした。トリッキーな部分は、特定の遺伝子の全項目を印刷したいということです。エントリはLOCUSという単語で始まり、//で終わり、その間のどこかに遺伝子名が含まれています。 grepのフラグ-A-Bおよびを使用して-C印刷できることを知っています。N文字列は前後の行と一致しますが、実際の項目の長さは可変です。 grepを使用して文字列(遺伝子名)を検索し、一致する項目の前のすべての行(「LOCUS」で始まる行を含む)とすべての行(項目の終わりを表す行を含む)を印刷するにはどうすればよいですか? "//" ?

私はすべての提案で開いています。文字列(「LOCUS」と「//」)などの項目と一致するように-Aフラグを立てる方法はありますか?-B代わりにawkを使用する必要がありますか?

編集:以下は簡単な入力例です。各レコードは「LOCUS」で始まり、「//」で終わります。この例には 3 つのレコードが含まれています。

LOCUS scaffold1|size100
/gene="gene1"
GATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
GATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
//
LOCUS scaffold99|size
/gene="gene2"
CGTTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
GATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
GATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
//
LOCUS scaffold199|size1000
/gene="gene3"
AGTTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
GATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
AGTTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
GATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
AGTTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
GATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
//

「gene2」を検索し、一致前の最初の「LOCUS」インスタンスから一致後の最初の「//」インスタンスまでテキストを印刷したいと思います。理想的には、次のような出力が必要です。

LOCUS scaffold99|size
/gene="gene2"
CGTTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
GATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
GATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
//

答え1

次の状況では非常に簡単ですawk

awk -vtarget=fox '
    /LOCUS/ { in_gene = 1 }
    in_gene { if (gene == "") gene = $0; else gene = gene ORS $0; }
    $0 ~ target { found = 1 }
    /\/\//  { if (in_gene && found) print gene
              gene = ""; in_gene = 0; found = 0
            }
    '
  • 変数targetを検索する文字列(遺伝子名)に設定します。私はこれをfox例として使用しています。
  • この言葉を見ると、LOCUS私たちは遺伝子を探していることがわかります。
  • 私たちが遺伝子に焦点を当てる限り、その内容は蓄積されます。最初の行(行)が変数LOCUSに割り当てられました。gene次に、古い値と追加された値の間に新しい行(ORS =出力レコード区切り文字)を使用して、現在の行()を変数に$0追加(追加)します。gene
  • 現在の遺伝子に探している遺伝子名が含まれている場合は、フラグを設定しますfound
  • 私たちは、遺伝子を見つけたら、現在の遺伝子が私たちが探している遺伝子であることを確認し、そうであればそれを印刷する/\/\//かなり醜い方法を使用しなければなりません。//その後、リセットして検索を続けます。探している遺伝子がファイル内で一度だけ発生すると確信している場合(または最初の発生のみを希望する場合)、ここで終了できます。

答え2

たびに遺伝子レコードが間にあることを指定したLOCUS...//場合は、次のことができます。

gawk '/gene2/{printf $0 RS}' RS='\n//\n' infile

私達は定義したRS\n各レコードは、「ewline //\newline」(含まれている行のみ)などの一意の値で終わり//、printfに一致する各レコードの/gene2/ログを記録して$0復元しますRS

メモ: 先行/末尾のスペース(スペース/タブ)が含まれる場合を管理するには、に変更RSできますが、RS='\n( |\t)*//( |\t)*\n'次のようにする必要があります。RT牛に似た一種の栄養awk拡張子)RSそのまままたは直接printf "//"

gawk '/gene2/{printf $0 RT}' RS='\n( |\t)*//( |\t)*\n' infile

~からman gawk:

RS デフォルトでは、改行レコードの区切り文字を入力します。

RT レコードターミネーター。ダイダイジRT指定した文字または正規表現に一致するテキストを入力するにはRS


:録画終了確認後、愚かな変数の設定RT入力のテキストと一致させるにはRS。いつRS単一文字で、RT同じ単一文字を含みます。しかしいつ RS正規表現RT正規表現に一致する実際の入力テキストを含みます。

答え3

sed -ne '
   /^LOCUS/,\|^//|!d
   H;/^LOCUS/h
   \|^/gene="gene2"|{
      s/.*//;x;H
   }
   \|^//|!d;g
   s/^\n//p
'       input_file

布材:

,¶ここでは範囲演算子を使用できます

¶ まず、正しい範囲、つまり//軌跡の開始範囲と終了範囲を選択します。

¶予約済みスペースに行を保存します。

¶ gene2のゴールデンラインに到達すると、いつ印刷するかを知らせるフラグで、先頭に改行文字を入れます。

¶line //は、予約領域の前に改行文字があるかどうかに応じて印刷アクティビティをトリガーします。

関連情報