私はタブで区切られた5つの列からなる何百ものテキストファイルを持っています。最初の列にはインデックスが含まれ、次の4つの列には発生回数が含まれます。ここで、値がゼロの3列(つまり、次の例では7行)を含む行数を計算しようとしています。
1 0 0 0 9
2 0 9 0 0
3 10 0 0 0
4 0 10 4 0
5 0 0 0 10
6 0 0 0 10
7 0 0 0 10
8 0 10 0 0
9 5 0 5 0
これをRからループにコーディングできますが、元のファイルにはそれぞれ6000万以上の行が含まれているので、awkまたはsedとwc -lを使用してこれを解決する方法がないかどうか疑問に思います。
ベストアンサー1
はい、次のことができますawk
。
awk '{
k=0;
for(i=2;i<=NF;i++){
if($i == 0){
k++
}
}
if(k==3){
tot++
}
}
END{
print tot
}' file
また、(GNU)sed
とwc
:
$ sed -nE '/\b0\b.*\b0\b.*\b0\b/p' file | wc -l
7
しかし、個人的にはPerlを代わりに使用します。
$ perl -ale '$tot++ if (grep{$_ == 0 } @F) == 3 }{ print $tot' file
7
または少し圧縮されていません。
$ perl -ale 'if( (grep{$_ == 0 } @F) == 3 ){
$tot++
}
END{
print $tot
}' file
7
そしてあなたのゴルファーのために:
$ perl -ale '(grep{$_==0}@F)==3&&$t++}{print$t' file
7
説明する
-ale
:-a
Perlをawkのように振る舞います。入力ファイルの各行を読み、それをスペースで分割して配列にします@F
。各呼び出しに対する入力の末尾の改行を-l
追加および削除し、各入力行に適用する必要があるスクリプト。\n
print
-e
$tot++ if (grep{$_ == 0 } @F) == 3
:$tot
正確に3つのフィールドがあるたびに1ずつ増加します0
。最初のフィールドは1から始まるので、0にはならないことがわかっているので、除外する必要はありません。}{
END{}
:これは、ファイルが処理された後に実行されるコードブロックを提供する簡単な方法です。したがって、}{ print $tot
値を含む3つのフィールドを含む行の総数が印刷されます0
。