대립유전자 빈도를 설명하는 파일이 있고 마지막 두 열의 빈도 중 하나가 0.01 이상인 경우 awk를 사용하여 행을 인쇄하려고 합니다. 주파수 파일의 형식은 다음과 같습니다. 저는 마지막 두 주파수에 관심이 있습니다.
2L 10000133 A 125/125 115/131 0/125 16/131
2L 10000374 A 121/124 143/143 3/124 0/143
awk에 대한 제한된 지식을 바탕으로 다음 코드를 작성했습니다.
cat myfile.txt |
awk ' BEGIN { {FS="/"}{OFS="\t"}
if( ($8>0) && ($8/$9 >= "0.01") || ($10>0) && ($10/$11 >= "0.01"))
{ print $1,$2 }
}' > myfilteredfile.txt
그러나 출력 파일 myfilteredfile.txt는 비어 있습니다. 출력 파일이 인쇄될 것으로 예상했습니다.
2L 10000133
2L 10000374
...두 행의 마지막 두 열의 빈도가 0.01보다 크거나 같기 때문입니다. 어떤 제안이 있으십니까?
답변1
기존 스크립트에는 두 가지 문제가 있습니다.
첫 번째는 구분 기호입니다. 공백과 슬래시로 분할하려면 해당 정규식을 지정하고 다음과 같이 사용해야 합니다 FS
.FS="[ /]+"
두 번째는 모든 코드가 BEGIN
블록 안에 있다는 것입니다. BEGIN
초기화 블록(또는 다른 곳)에 구분 기호가 필요합니다 .예를 들어특정 AWK 매개변수 사용) 그런 다음 matcher 블록을 사용하여 해당 라인을 처리합니다.
이 버전의 작동 방식:
awk 'BEGIN { FS="[ /]+"; OFS="\t" }
(($8>0) && ($8/$9 >= "0.01") || ($10>0) && ($10/$11 >= "0.01")) {
print $1, $2
}' myfile.txt
엄밀히 말하면 숫자 값을 일치시키려고 하므로 0.01
대신 사용하는 것이 더 좋습니다 ."0.01"
awk 'BEGIN { FS="[ /]+"; OFS="\t" }
(($8>0) && ($8/$9 >= 0.01) || ($10>0) && ($10/$11 >= 0.01)) {
print $1, $2
}' myfile.txt
답변2
$ awk '{ split($(NF-1),a,/\//) } { split($NF,b,/\//) } a[1]/a[2] > 0.01 || b[1]/b[2] > 0.01 { print $1, $2 }' file.in
2L 10000133
2L 10000374
이렇게 하면 마지막 두 필드를 문자별로 개별적으로 분할 /
하고 해당 부분을 두 개의 배열 a
과 에 저장합니다 b
. 나누기 결과가 0.01보다 큰 숫자가 되면 처음 두 필드가 출력됩니다.
$NF
입력 레코드(행)의 마지막 필드(열) 값입니다. $(NF-1)
두 번째 필드의 값 입니다 .
코드의 문제는 BEGIN
do everything 블록 내에서 모든 작업을 수행한다는 것입니다. 이 블록은 주로 초기화에 사용되며 실행됩니다.앞으로실제로 읽은 데이터가 없습니다. FS
다른 답변에서 지적한 선택 값에도 문제가 있습니다.
또한 숫자로 사용될 때 숫자를 인용할 필요가 없습니다.
답변3
In 부분 awk
은 BEGIN{...}
입력에서 입력 줄을 읽기 전에 실행되므로 awk
코드에서 실제로 입력을 읽지 않으므로 아무 것도 반환하지 않습니다. 먹이를 주고 싶다면 를 사용해야 getline
하지만 한 줄만 읽게 되므로 for
루프를 사용하여 모두 읽을 수 있습니다.
또 다른 문제는 이를 사용하여 FS="/"
행을 로 구분된 필드로 분할 하는 경우이지만 최대 필드가 5개에 불과하고 제출된 필드가 다음과 같기 때문에 /
문제가 없습니다 .$8
125 115
131 0
125 16
이 코드를 사용하여 원하는 것을 얻을 수 있습니다. 또한 awk
파일에서 직접 읽을 수 있으므로 cat
거기에서 사용할 필요가 없습니다.
awk -F'[/ ]+' 'BEGIN{ OFS="\t"}
{if( ($8>0) && ($8/$9 >= 0.01) || ($10>0) && ($10/$11 >= 0.01))
{ print $1,$2 }
}' infile