awkスクリプトで除算を使用する

awkスクリプトで除算を使用する

対立遺伝子の頻度を記述するファイルがあり、最後の2列の頻度の1つが0.01以上の場合は、awkを使用して行を印刷しようとします。周波数ファイルの形式は次のとおりです。私は最後の2つの周波数に興味があります。

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

これは、2行の最後の2列の頻度が0.01以上であるためです。どんな提案がありますか?

答え1

既存のスクリプトには2つの問題があります。

最初は区切り記号です。スペースとスラッシュに分割するには、対応する正規表現を指定し、次のように使用する必要がありますFSFS="[ /]+"

2番目は、すべてのコードがBEGINブロック内にあることです。BEGIN初期化ブロック(または他の場所)に区切り文字が必要です。例えば特定のAWKパラメータを使用)次に、マッチャブロックを使用してその行を処理します。

このバージョンの仕組み:

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

これにより、最後の2つのフィールドが文字ごとに別々に分割され、/その部分が2つの配列aに格納されますb。除算結果が0.01より大きい数値になると、最初の2つのフィールドが出力されます。

$NF入力レコード(行)の最後のフィールド(列)値。$(NF-1)2番目のフィールドの値。


コードの問題は、BEGINdo everythingブロック内ですべての操作を実行することです。このブロックは主に初期化に使用され、実行されます。今後実際に読み取ったデータはありません。FS他の回答で指摘した選択値にも問題があります。

また、数字として使用するときに数字を引用する必要はありません。

答え3

In部分awkBEGIN{...}入力から入力行を読み取る前に実行されるため、コードawkから実際に入力を読み取らないため、何も返しません。餌を与えたい場合はを使用する必要がありますgetlineが、1行だけを読み取るので、forループを使用してすべてを読むことができます。

もう1つの問題は、これを使用してFS="/"行を区切りフィールドに分割する場合ですが、最大フィールドは5つにすぎず、送信されたフィールドは次のようになるため/問題はありません。$8125 115131 0125 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

関連情報