使用 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)不打印任何内容时,当我将条件更改为 be 时,($3 <= $upper)它​​会打印但不过滤任何内容。我尝试检查下限和上限变量是否合理。 1,手动检查我的 snps 的位置,我发现有一些 snps 位于两个阈值之间。第二,通过打印出变量的长度来${#foo}打印出正确的长度,因此我们可以假设没有隐藏字符使其充当字符串。

有人能给我建议吗?

TL;DR 尝试抓取给定范围内位置的项目,awk 没有按我的预期工作

答案1

Shell 变量是单引号的。在单引号中,变量不会扩展。

$ 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

相关内容