특정 필드가 있는 행만 가져오기

특정 필드가 있는 행만 가져오기
#CHROM  POS     T1      T10     T11     T12     T13     T2      T3      T4      T5      T6      T106    T107    T108    T109    T110    T112    T114    T116    T120    T122    T125    T128    T129    T130
Aradu.A01       300806  H       B       B       B       B       B       B       B       H       B       B       H       B       B       B       B       B       B       B       B       B       B       B
Aradu.A01       386907  A       A       A       A       A       A       A       A       A       A       A       A       H       A       A       A       A       A       H       A       A       A       A
Aradu.A01       463100  B       B       A       A       A       A       A       H       B       A       A       H       H       H       H       H       B       A       B       A       H       H       A
Aradu.A01       471639  A       A       A       A       H       A       A       H       A       A       H       A       A       A       A       A       H       A       A       A       H       A       A
Aradu.A01       644024  H       B       B       B       B       B       B       B       H       H       B       H       H       B       B       B       H       B       H       B       B       B       H
Aradu.A01       756331  H       H       H       H       H       H       H       H       B       B       B       H       H       H       H       H       B       H       H       H       B       B       B
Aradu.A01       768081  A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A
Aradu.A01       783066  A       A       H       A       H       H       A       A       A       A       H       A       H       A       A       A       A       A       A       H       A       A       H
Aradu.A01       812865  H       B       H       H       H       H       H       H       H       H       H       H       H       H       H       H       B       B       H       H       B       B       H
Aradu.A01       976731  A       H       A       H       H       A       H       H       A       H       H       A       H       H       A       A       H       A       H       A       A       A       H
Aradu.A01       1089311 A       H       H       H       H       A       A       A       H       A       H       B       A       H       H       H       H       H       A       A       H       H       H
Aradu.A01       1089991 A       A       A       H       A       A       H       A       A       H       A       A       A       A       H       A       A       A       A       A       A       A       H
Aradu.A01       1113781 H       H       H       H       H       H       H       A       H       H       H       H       H       H       A       H       H       A       H       A       H       H       H
Aradu.A01       1160441 B       B       B       B       B       B       H       B       H       B       B       B       B       B       H       B       B       B       B       B       B       B       B
Aradu.A01       1638873 B       H       B       B       H       B       B       B       B       B       B       B       H       H       H       B       B       B       B       B       H       B       B
Aradu.A01       1638907 B       H       B       B       H       B       B       B       H       B       B       B       H       H       H       B       B       B       B       B       H       B       B

"A" 및 "B" 필드가 포함된 행만 가져오는 awk 코드를 작성하는 데 도움을 줄 수 있는 사람이 있나요?
1) "A"와 "H"만 있는 행, 2) "B"와 "H"만 있는 행은 고려되지 않습니다 .

각각은 A와 B를 모두 가지고 있어야 합니다. A, B와 함께 H도 나타나는 경우 해당 라인도 고려해야 합니다. 요약하자면, "A"와 "B"를 포함하는 행만 필요합니다. "A"와 "B"와 함께 "H"가 존재하는 경우 해당 행도 고려해야 합니다.

NR>1  {for(i=3;i<=NF;i++)
        { if ( $i ~ "A" && $i ~ "B" && $1 ~ "H" ) ;
       } ## if ;
       ## for loop is done
       print ;

위의 코드는 출력 파일을 입력 파일로 반환합니다. }

답변1

스크립트에 몇 가지 문제가 있습니다.

  • 두 개의 "A"와 일치하는 필드가 있는지 테스트합니다.그리고동시에 "B". 필드가 단 한 문자인 경우(따라서 "AB", "BAA" 등을 얻을 수 없음) 이는 결코 사실이 아닙니다.
  • 보고있어, 나타나든 말든 H상관없어H
  • 루프를 통과할 때마다 (첫 번째 필드)를 H찾습니다 .$1
  • 이러한 모든 테스트의 결과는 구별할 수 없습니다. if테스트에 일치하는 작업이 없습니다. print각 라인마다 항상 도달 범위가 있습니다.

트랙 A그리고B가 같은 줄(다른 필드)에 나타나면 각각에 대해 변수를 사용할 수 있습니다.

NR>1  {
    #beginning of line - no As or Bs seen yet
    A=0
    B=0
    #looping over all fields except the first two
    #break as soon as both A and B found
    for(i=3; A*B == 0 && i<=NF; i++) {
        if ( $i ~ "A" ) A=1
        if ( $i ~ "B" ) B=1
   }
    #print line if A and B were found
    if (A && B) print
}

답변2

이것은 해결책은 아니지만 awk다음과 같이 하면 grep효과가 있는 것 같습니다.

egrep '^Aradu\.[A-Z][0-9]{2}.*A.*B|^Aradu\.[A-Z][0-9]{2}.*B.*A' aradu
Aradu.A01       463100  B       B       A       A       A       A       A       H       B       A       A       H       H       H       H       H       B       A       B       A       H       H       A
Aradu.A01       1089311 A       H       H       H       H       A       A       A       H       A       H       B       A       H       H       H       H       H       A       A       H       H       H

aradu샘플 파일은 어디에 있습니까?

편집, 정규식 분석:
^Aradu\.[A-Z][0-9]{2}= "Aradu"로 시작하고 텍스트 ".", 대문자, 정수가 두 번 나오는 줄입니다.
.*A.*B= 뒤에 임의의 문자( .*)가 오고 그 뒤에 리터럴 "A"가 오고 그 뒤에 리터럴 "B"가 옵니다
|= 논리적 OR.
(표현의 시작 부분이 동일할 때까지)
.*B.*A= 임의의 문자, 횟수 제한 없이 반복되고 그 뒤에 리터럴 "B"가 오고 그 뒤에 리터럴 "A"가 옵니다.

grep(논리적 AND) 연산자가 없으면 &&이 행은 (내가 아는 한) 검색할 수 있는 가장 가까운 행입니다 A && B || B && A.

관련 정보