別のファイル内の各クエリの2行目を印刷する必要があります。

別のファイル内の各クエリの2行目を印刷する必要があります。

爆発結果からヒットIDと無ヒットIDを抽出したい

たとえば、私の爆発出力には次のものがあります。

> Query= TRINITY_DN109574_c0_g1_i1

Length=277
***** No hits found *****
Lambda      K        H        a         alpha
   0.318    0.134    0.401    0.792     4.96 
Gapped
Lambda      K        H        a         alpha    sigma
   0.267   0.0410    0.140     1.90     42.6     43.6 
Effective search space used: 749080088160

> Query= TRINITY_DN109587_c0_g1_i1

Length=312
***** No hits found *****
Lambda      K        H        a         alpha
   0.318    0.134    0.401    0.792     4.96 
Gapped
Lambda      K        H        a         alpha    sigma
   0.267   0.0410    0.140     1.90     42.6     43.6

> Query= TRINITY_DN109586_c0_g2_i1

Length=472

Sequences producing significant alignments:                          
                                    (Bits)  Value
protein LOC111635341 n=1...  104     1e-23
  UniRef90_UPI000C6CD8E3 uncharacterized protein LOC111632564 n=1...  103     1e-23
  UniRef90_UPI000C6CAADE uncharacterized protein LOC111636326 n=1...  103     3e-23

私は次のようなものが欲しい:

TRINITY_DN109574_c0_g1_i1          No hits
TRINITY_DN109587_c0_g1_i1          No hits 
TRINITY_DN109586_c0_g2_i1          Sequences producing significant alignments: 

これは、別のファイル内の各クエリの2行目を印刷する必要があることを意味します。

答え1

sed -E "/^$/d" file | awk '/> Query/{printf "%s\t", $3; nr[NR+2]}; NR in nr '

出力

TRINITY_DN109574_c0_g1_i1       ***** No hits found *****
TRINITY_DN109587_c0_g1_i1       ***** No hits found *****
TRINITY_DN109586_c0_g2_i1       Sequences producing significant alignments:

牙...

あなたのIDとヒットラインの間隔はヒットするかどうかによって異なりますが、余分な空の行によってのみ間隔が変わるため、空の行をすべて削除すると

sed -E "/^$/d" file 

その後、ヒット/失敗行は常にクエリの前の2行です。次に、パイプを介して|クエリawkで始まる行のみを探します。

awk '/> Query/'

$3ただし、クエリ行には3番目(スペースで区切られた)フィールドのみが必要です。これはあなたのIDだからです。

awk '/> Query/{print $3}'

正規表現の一致を見つけるたびに、一致するヒット行の行番号を計算して配列に保存しようとしています。私は配列を呼び出し、nr私たちが興味のあるヒット行は現在一致する行NR+ 2です。

awk '/> Query/{print $3; nr[NR+2]}'

NR最後に、2番目の条件を追加して、正規表現と一致しない行が配列にあることを確認してnr印刷します。また、IDの末尾にヒットを出力するように最初の項目をprint変更してください。printf

awk '/> Query/{printf "%s\t", $3; nr[NR+2]}; NR in nr;'

NR次の正規表現の一致よりも多くの数字を追加すると、このソリューションは中断されます。

答え2

GNU sedを使用してクエリ行から始まり、パターン空間に行を累積し、空白行を捨て、空でない行3つが累積されると印刷します。

$ sed -e '
    :loop
        /\n.*\n/{
            s//\t/
            s/^> Query=//p
         }
         /^> Query=/!d
         $d;N
         s/\n$//
     bloop
' file

Perlを使用してファイルを読み取り、クエリ行を取得し、空白行をスキップし、空でない最初の行をスキップします。

$ perl -0777ne 'print "$1\t$2" while /^> Query=\h+(.*)\n\n*.*\n\n*(.*\n)/mg' file

答え3

PCREモードでは、GNU grepを使用して最初にクエリ行を抽出し、空でない2行を抽出し、中央の空行の範囲は0から倍数まで可能です。

$ < file grep -zoP '(?m:^> Query=\h+\K.*\n\n*(.*\n\n*){2})' |
    tr -d '\0' | tr -s '\n' |
    sed -e 'h;n;n;H;g;s/\n/\t/'

範囲演算子を使用する別の方法...

$ perl -lane '
    $e = (/^> Query=/ && $c==0) ... (/\S/ && $c==2);
    next if !length($e) || !@F;
    $q = $F[2]       if $e == 1;
    print "$q\t$_" if $e =~ /E0/;
    $c = $c == 2 ? 0 : $c+1;
  ' file 

関連情報