특정 기둥 패턴의 위치 찾기

특정 기둥 패턴의 위치 찾기

약간의 처리 후에 다음과 같은 파일이 생겼습니다.

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", 두 번째 열을 "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

와 같은 방법스티븐 키트의 답변이지만 추가 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

관련 정보