私は遺伝子を同じ染色体の複数の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