awk의 행과 열을 반복하여 각 셀의 특정 하위 문자열을 계산합니다.

awk의 행과 열을 반복하여 각 셀의 특정 하위 문자열을 계산합니다.

138개의 첫 번째 헤더 행(#으로 시작)과 행의 기타 데이터(snp(322045))와 열의 일부 정보가 있는 환자(처음 10개 행)가 포함된 .vcf 파일이 있습니다. 스크립트 bash를 사용하여 각 행의 숫자를 계산합니다. "0|0"(초기 부분)과 다른 해당 행의 셀 수: 여기 내 스크립트가 있습니다.

for j in {139..322045}

    do
     c=0
     awk -v var=$c -v j=$j 'NR==j{for(i=10; i<=NF; i++) {if(substr($i,1,3)!="0|0") var++}} END{ print $1 ":" $2 "\t" var }' file.vcf >> out.txt
    done

이것은입력하다:

> #<info>
> #..
> # . . . 
21  9411245  x  C   A   505  PASS   AC=2   GT:AD:DP:GQ:PL   0|0:11  0|0:12
21  9411246  y  C   T   505  PASS   AC=2   GT:AD:DP:GQ:PL   0|0:11  1|0:13

(탭으로 구분된 열) 그런 다음 다음으로 연결된 첫 번째와 두 번째 열을 인쇄합니다. 그리고 count; 하지만 완전히 작동하지 않습니다. 2개의 행만 있는 하위 집합을 사용하면 완벽하게 작동합니다. 이것은결과

21:48111872 2
21:48111872 1
21:48111872 0
21:48111872 2

행을 반복합니다

어떻게 해결할 수 있나요? 미리 감사드리며, 문제를 해결하려면 간단한 설명을 적어주세요.

알아채다계산하는데 시간이 많이 걸립니다. ({139..160}에도 사용됨)

답변1

작동하지 않는 이유는 인쇄 $1중이고 $2블록에 있기 때문입니다 END{}. END{}입력 파일의 마지막 줄을 읽은 후 한 번만 실행합니다. 따라서 $1and는 $2항상 마지막 행의 첫 번째 및 두 번째 필드가 됩니다.

그럼에도 불구하고 이는 텍스트 파일을 구문 분석하는 매우 비효율적인 방법입니다. 루프가 반복될 때마다 전체 내용을 읽고 있습니다. 쉘 루프는매우느린. 그래서 당신은 매우 느린 루프를 사용하고 있습니다그리고불필요하게 수천 줄의 awk를 반복해서 읽습니다.

쉘 루프를 사용하는 대신 awk에서 모든 작업을 수행하십시오.

$ awk -F"\t" '/^[^#]/{var=0; for(i=10; i<=NF; i++) {if(substr($i,1,3)!="0|0") var++} print $1 ":" $2 "\t" var }' foo.vcf 
21:9411245  0
21:9411246  1

또는 조금 더 간결하게 말하면 다음과 같습니다.

awk -F"\t" '/^[^#]/{
        var=0; 
        for(i=10; i<=NF; i++) {
            if(substr($i,1,3)!="0|0"){
                var++
            } 
        }
        print $1 ":" $2 "\t" var 
    }' foo.vcf 

설명하다

  • -F"\t": 입력 필드 구분 기호를 탭으로 설정합니다.
  • /^[^#]/{ ... }: ( )가 아닌 문자로 시작하는 줄에 대해서만 이 작업을 수행합니다( /^a/로 시작하는 줄과 일치함).a#[^#]
  • var=0;: var각 입력 라인을 다시 0으로 설정합니다.
  • for(i=10; i<=NF; i++) {if(substr($i,1,3)!="0|0") var++}: 이것은 유전자형이 아닌 것이 발견된 횟수를 계산하는 원본 코드입니다 0|0.
  • print $1 ":" $2 "\t" var:다시 말하지만, 코드는 이제 END{}블록 외부에 있으므로 끝뿐만 아니라 모든 줄에서 실행됩니다.

그게 다야. 쉘 루프가 필요하지 않으며 몇 초 밖에 걸리지 않습니다.

관련 정보