2 つの条件を使用したファイルのフィルタリング

2 つの条件を使用したファイルのフィルタリング

次のファイルがあります

> head map.stats
ID=NbD053289.1.mrna1;Name=NbD053289.1;Parent=NbD053289.1.path1;coverage=100.0;identity=100.0;matches=702;mismatches=0;indels=0;unknowns=0
ID=NbD053288.1.mrna1;Name=NbD053288.1;Parent=NbD053288.1.path1;coverage=100.0;identity=99.8;matches=482;mismatches=1;indels=0;unknowns=0
ID=NbD053287.1.mrna1;Name=NbD053287.1;Parent=NbD053287.1.path1;coverage=100.0;identity=94.1;matches=738;mismatches=0;indels=46;unknowns=0
ID=NbD053281.1.mrna1;Name=NbD053281.1;Parent=NbD053281.1.path1;coverage=99.3;identity=99.1;matches=1476;mismatches=14;indels=0;unknowns=0

$identity >= 95 && $coverage == 100この出力を得るためにフィルタリングしたいと思います。

ID=NbD053289.1.mrna1;Name=NbD053289.1;Parent=NbD053289.1.path1;coverage=100.0;identity=100.0;matches=702;mismatches=0;indels=0;unknowns=0
ID=NbD053288.1.mrna1;Name=NbD053288.1;Parent=NbD053288.1.path1;coverage=100.0;identity=99.8;matches=482;mismatches=1;indels=0;unknowns=0

試してみましたgrep -oP '(?<=identity=).*?(?=;)' map.stats | awk '$1 >= 99'が、それほど遠くはできませんでした。このフィルタリングはどのように可能ですか?

事前にありがとう

答え1

別のアプローチは次のとおりです。

$ awk -F'[;=]' '$10>=95 && $8 == 100' file
ID=NbD053289.1.mrna1;Name=NbD053289.1;Parent=NbD053289.1.path1;coverage=100.0;identity=100.0;matches=702;mismatches=0;indels=0;unknowns=0
ID=NbD053288.1.mrna1;Name=NbD053288.1;Parent=NbD053288.1.path1;coverage=100.0;identity=99.8;matches=482;mismatches=1;indels=0;unknowns=0

秘密は、フィールド区切り文字を;またはに設定することです=(そう-F'[;=]'します)。すると、 の値はidentity10 番目のフィールドになり、 の値はcoverage8 番目のフィールドになります。awk式がtrueと評価された場合、デフォルトのジョブは現在の行を印刷することであるため、これら2つの条件に一致するすべての行が印刷されることを意味します$10>=95 && $8 == 100


実際にはGNUでもこれを行うことができますが、完全な行が必要であり、振り返る理由がないため、grepそのオプションは必要ありません。-o必要なのは範囲を定義するだけです。 ( )95までの値が必要なので、次の間に数字が必要であることを意味します。100>=95959100

$ grep  -P 'coverage=100.0.*identity=(9[5..9]|100)' file 
ID=NbD053289.1.mrna1;Name=NbD053289.1;Parent=NbD053289.1.path1;coverage=100.0;identity=100.0;matches=702;mismatches=0;indels=0;unknowns=0
ID=NbD053288.1.mrna1;Name=NbD053288.1;Parent=NbD053288.1.path1;coverage=100.0;identity=99.8;matches=482;mismatches=1;indels=0;unknowns=0

私は、同一性が100より大きい値を持つことができないと仮定していることに注意してください。これはおそらく配列の保存を見ており、100%同じものよりも同様の結果が得られないため、安全な仮定のようです。

答え2

まず、次のようにフィールドを数値に変換してみましょう。

awk -F= 'NR==1 { for(i=1;i<=NF;i++) printf "%2d %s\n",i,$i ;}' file
 1 ID
 2 NbD053289.1.mrna1;Name
 3 NbD053289.1;Parent
 4 NbD053289.1.path1;coverage
 5 100.0;identity
 6 100.0;matches
 7 702;mismatches
 8 0;indels
 9 0;unknowns
10 0

したがって、Coverageは5、Identityは6です。

==次に、awkは文字列と一致するため、直接使用できないため、+1を使用して数値に変換します。

この出力

awk -F= '$6+1>96 && ($5+1) == 101' file
ID=NbD053289.1.mrna1;Name=NbD053289.1;Parent=NbD053289.1.path1;coverage=100.0;identity=100.0;matches=702;mismatches=0;indels=0;unknowns=0
ID=NbD053288.1.mrna1;Name=NbD053288.1;Parent=NbD053288.1.path1;coverage=100.0;identity=99.8;matches=482;mismatches=1;indels=0;unknowns=0

どこ

  • -F==awkに区切り文字として使用するように指示する
  • $6+1>96上記のように数値に変換してフィルタリングします。

関連情報