関心のある各列の特定の値に基づいて複数の列を持つテーブルをフィルタリングする方法を知りたいです。
ここにこの例があります。
Chr1 16644 0 0 1 1
Chr1 16645 0 0 1 1
Chr1 16646 0 0 1 1
Chr1 16647 0 0 1 1
Chr1 16648 0 0 1 1
Chr1 16649 0 0 1 1
Chr1 16650 0 0 1 1
Chr1 16651 0 0 1 1
Chr1 16782 0 0 0 0
Chr1 16783 0 0 0 0
Chr1 16784 0 0 0 0
Chr1 16785 0 0 0 0
Chr1 16786 0 0 1 1
Chr1 16787 0 0 1 1
Chr1 16788 0 0 1 1
Chr1 16789 0 0 1 1
Chr1 16790 0 0 1 1
3、4、5、6列から0を含むすべての行を削除したいです。
私はすでに試しました。
cat STARsamples_read_depth.txt | awk '$3 != 0 && $4 != 0&& $5 != 0 && $6 != 0' | less
ただし、4列すべてではなく、一部の列のみがゼロの行も削除します。
それを行う方法はありますか?
ありがとう
アサ
答え1
awkを使用すると、関心のあるフィールドをリンクすると、ゼロ以外の数値が生成されるかどうかをテストできます。
$ awk '($3$4$5$6)+0' file
Chr1 16644 0 0 1 1
Chr1 16645 0 0 1 1
Chr1 16646 0 0 1 1
Chr1 16647 0 0 1 1
Chr1 16648 0 0 1 1
Chr1 16649 0 0 1 1
Chr1 16650 0 0 1 1
Chr1 16651 0 0 1 1
Chr1 16786 0 0 1 1
Chr1 16787 0 0 1 1
Chr1 16788 0 0 1 1
Chr1 16789 0 0 1 1
Chr1 16790 0 0 1 1
または、何らかの理由で各フィールドを個別にテストする場合は、次の手順を実行します。
$ awk '{for (i=3; i<=6; i++) if ($i != 0) { print; next } }' file
Chr1 16644 0 0 1 1
Chr1 16645 0 0 1 1
Chr1 16646 0 0 1 1
Chr1 16647 0 0 1 1
Chr1 16648 0 0 1 1
Chr1 16649 0 0 1 1
Chr1 16650 0 0 1 1
Chr1 16651 0 0 1 1
Chr1 16786 0 0 1 1
Chr1 16787 0 0 1 1
Chr1 16788 0 0 1 1
Chr1 16789 0 0 1 1
Chr1 16790 0 0 1 1
質問に示すように、入力が整数でない可能性がある場合(コメントを参照)、上記の2番目のスクリプトを使用するか、接続の数値比較の代わりに文字列にすることができます。
awk '($3$4$5$6) != "0000"' file
答え2
コメントで@Devonが述べ||
たように&&
。
その理由は、少なくとも次の行を表示したいからです。一つ3、4、5、6列の値は0とは異なります。
これは理解のもう一つの方法です。列がすべてゼロの行を削除しようとしています。反対の観点から始めましょう。印刷この列はすべてゼロの行です。これはとても簡単です。
awk '$3 == 0 && $4 == 0 && $5 == 0 && $6 == 0'
今あなたが欲しい上下反転このステートメントはすべての行を表示します。いいえ上記の条件を満たしてください。ですから、その言葉を否定すればいいのです。
awk '(!($3 == 0 && $4 == 0 && $5 == 0 && $6 == 0))'
しかし、上記のコマンドもあなたの要件を満たしています。
とにかく、論理否定ルール、命題の否定「ㅏそして第二」はい「AじゃないまたはBではない」。したがって、このステートメントを拒否するには、次のようにします。
$3 == 0 && $4 == 0 && $5 == 0 && $6 == 0
すべての式を否定し、すべて変換する必要があります。「そして」オペレーター「または」。
$3 != 0 || $4 != 0 || $5 != 0 || $6 != 0
これで、コマンドが機能しない理由をよりよく理解できます。使用するステートメントの否定は次のとおりです。
$3 == 0 || $4 == 0 || $5 == 0 || $6 == 0
これは、少なくとも次のすべての行を削除することを意味します。一つ列(すべてではない)は0です。
答え3
使用awk
:
$ awk '!/(\s+0){4}$/' file
Or
$ awk '!/([[:space:]]+0){4}$/' file
2番目のコマンドにはPOSIX awkが必要です。
すべてのフィールド(つまり$3
、、、、$4
および0)を含むレコードを削除します。 @EdMortonが提案したように$5
$6
$ awk '{ x=4;for(i=3;i<=6;i++) if ($i==0) {x--;} }x' file
$3
$4
、$5
およびフィールドのいずれかが$6
ゼロの場合、そのフィールドを含むレコードを削除します。
$ awk '{ x=1;for(i=3;i<=6;i++) if ($i==0) {x=0;break;} }x'
forループは、(i=3;i<=6;i++)
フィールド3、4、5、6をフィルタリングするために発生します。