awk를 사용하여 범위 간 필터링

awk를 사용하여 범위 간 필터링

나는 유전자를 동일한 염색체에 있는 다수의 snps와 비교하는 코드를 가지고 있습니다. 그러기 위해서는 서로 +/- 1000000 베이스 내에 있는 유전자와 snps만 비교하고 싶은데 awk를 사용하여 필터링하려고 하면 작동하지 않습니다.

내가 추출한 파일은 다음과 같습니다.

CHR# SNP_ID    POS     samp_1 samp_2 ...
chr1 rs1212 174654646  0      2      ...
chr1 rs1331 321311111  1      1      ...
...  ...    ...        ...    ...    ...

내 필터링 과정은 다음과 같습니다

upper_bound=$(expr $gene_stop + 1000000)
lower_bound=$(expr $gene_start - 1000000)
zcat chr1.genotypes.txt.gz | tail -n +2 | awk '{if ($3 >= $lower_bound && $3 <= $upper_bound) print $0}' > tmp_filtered

현재 빈 파일을 출력하고 있습니다. awk 조건을 아무것도 인쇄하지 않도록 변경하면 인쇄는 되지만 아무것도 필터링하지 않도록 ($3 >= $lower_bound)조건을 변경하면 됩니다 . ($3 <= $upper)하한 변수와 상한 변수가 합리적인지 확인하려고 합니다. 1. 내 snps의 위치를 ​​수동으로 확인했는데 일부 snps가 두 임계값 사이에 있는 것을 발견했습니다. 둘째, 변수의 길이를 출력하여 ${#foo}올바른 길이를 출력하므로 문자열로 작동하게 만드는 숨겨진 문자가 없다고 가정할 수 있습니다.

누구든지 나에게 조언을 해줄 수 있습니까?

TL;DR 주어진 범위에서 항목을 가져오려고 하면 awk가 예상대로 작동하지 않습니다.

답변1

쉘 변수는 작은따옴표로 묶입니다. 작은따옴표 내에서는 변수가 확장되지 않습니다.

$ start=100
$ echo '$start'
$start

awk에서도 같은 일이 발생합니다.

$ start=100
$ echo awk '$3>=$start'
awk $3>=$start

일반적인 해결책은 다음을 사용하여 값을 설정하는 것입니다 -v.

awk -vvar1=$lower -vvar2=$upper '{if ($3 >= var1 && $3 <= $var2) print $0}'

따라서 스크립트는 다음과 함께 작동해야 합니다.

up_b=$(expr $gene_stop + 1000000)
lo_b=$(expr $gene_start - 1000000)
zcat chr1.genotypes.txt.gz | tail -n +2 | 
awk -vlo=$lo_b -vup=$up_b '{if ($3 >= lo && $3 <= up) print $0}' > tmp_filtered

관련 정보