特定の柱パターンの位置を見つける

特定の柱パターンの位置を見つける

少し処理した後、次のようなファイルがありました。

ALA 251
VAL 252
TYR 253
LYS 254
SER 255
ALA 256
ALA 257
MET 258
LEU 259
ASP 260
MET 261
THR 262
GLY 263
ALA 264
GLY 265
TYR 266
VAL 267
TRP 268

最初の列を「res」、2番目の列を「num」とします。 「res」は常に3文字で構成され、「num」は1〜4個の数字で構成されます。

次のように、4つの連続した「res」からなる正確な列パターンの最初の「res」に対応する位置(列「num」の値)を抽出する方法を探しています。

TYR
LYS
SER
ALA

この場合、表示されるファイルとモードに応じて、出力は次のようになります。

253

私はawkで何度も試しました。可能なようですが、今は実力が不足しています。良いユーザーがこれについて提案をしてくれてありがとう。

答え1

しかし、テデン~の良いアドバイス、次のAWKスクリプトが操作を実行できます。

$1 == "TYR" { seq = $1; start = $2; next }
($1 == "LYS" && seq == "TYR") || ($1 == "SER" && seq == "LYS") { seq = $1; next }
$1 == "ALA" && seq == "SER" { print start }
{ seq = "" }

これは開始位置を見つけて覚えています。また、、TYR正しい順序で一致し、各ステップで前の項目を順番に記録します。一致しない行がある場合、シーケンスは消去されます。TYRLYSSERseq

答え2

スライドウィンドウsed

解析.sed

# Establish the sliding window
1N
2N

# Maintain the sliding window
N

# Match the desired pattern to the current window
/^TYR \(.*\)\nLYS .*\nSER .*\nALA .*$/ { 
  h;                           # Save the window in hold space
  s//\1/p;                     # Extract desired output
  x;                           # Re-establish window
}

# Maintain the sliding window
D

次のように実行します。

sed -nf parse.sed infile

出力:

253

答え3

のような方法Steven Kitの答えしかし、追加のseq変数はありません。代わりに、連続した「数字」を使用して、現在の行が私たちが探しているセットに属しているかどうかを判断します。

awk '{
  if ($1=="TYR") {
    i=$2 # remember index
  }
  else if (i!=0) { 
    if ($2==i+1 && $1=="LYS" || $2==i+2 && $1=="SER" || $2==i+3 && $1=="ALA") {
      if ($2==i+3) { # are we there yet?
        print i; exit
      }
    }
    else {
      i=0 # nope, reset index
    }
  }
}' file

(読みやすくするために不要な中括弧とインデントを維持しました。)

答え4

スライドウィンドウを使用してこれを行うことができます。

解析.awk

# Split the pattern into the `p` array and remember how many there are in `n`
BEGIN { n = split(pat, p, "\n") }

# Collect n lines into the `A` array
NR <= n { A[NR] = $0; next }

# Maintain the sliding window after n lines
NR  > n {
  for(i=2; i<=n; i++)
    A[i-1] = A[i]
  A[n] = $0
}

# Test if the current window contains the pattern
{
  hit = 1
  for(i=1; i<=n; i++) {
    split(A[i], x)
    if(x[1] != p[i]) {
      hit = 0
      break
    }
  }

  # If the window matches print the second column
  if(hit) {
    split(A[1], x)
    print x[2]
  }
}

次のように実行します。

awk -v pat="$(< patternfile)" -f parse.awk infile

出力:

253

関連情報