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が2つのしきい値の間にあることがわかりました。第二に、変数の長さを出力して${#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

おすすめ記事