How can I filter a tab-delimited contribution by the number of fields with a given value?

My data (tab divided):

1   0   0   1   0   1   1   0   1
1   1   0   1   0   1   0   1   1
1   1   1   1   1   1   1   1   1
0   0   0   0   0   0   0   0   0
...

how can I grep strings with exact, for example, 5 '1's, ideal output:

1   0   0   1   0   1   1   0   1

Also, how can I use grep strings with equal to or greater than (> =) 5 '1's, ideal output:

1   0   0   1   0   1   1   0   1
1   1   0   1   0   1   0   1   1
1   1   1   1   1   1   1   1   1

I tried,

grep 1$'\t'1$'\t'1$'\t'1$'\t'1

however, this will only output sequential '1, which is not all I want.

I wonder if there will be any easy way to achieve this, thanks!

+4
source share
5 answers

anishane answer , grep, , , , , .

awk, , ( , , ).

, GNU awk, :

5 1 s:

awk -v FPAT='\\<1\\>' 'NF==5' file

5 1 s:

awk -v FPAT='\\<1\\>' 'NF>=5' file
  • FPAT - GNU awk, , , ( FS -F):

    • '\\<1\\>' "" 1 ( ) , \< \>; \ , , awk, "" \ s.
  • NF , . true, ( : NF==5 NF==5 { print } , , NF==5 { print $0 }).


A POSIX- awk :

5 1 s:

awk '{ l=$0; gsub("[\t0]", "") }; length($0)==5 { print l }' file

5 1 s:

awk '{ l=$0; gsub("[\t0]", "") }; length($0)>=5 { print l }' file
  • l=$0 ($0) l.

  • gsub("[\t0]", "") \t 0. , ( ) 1 ( ).

  • length($0)==5 { print l } (l), 1 (.. 1 ($0)) ) .

+4

grep. .

$ cat countme
1   0   0   1   0   1   1   0   1
1   1   0   1   0   1   0   1   1
1   1   1   1   1   1   1   1   1
0   0   0   0   0   0   0   0   0

$ grep -P '^[0\t]*(1[0\t]*){5}[0\t]*$' countme # Match exactly 5
1   0   0   1   0   1   1   0   1

$ grep -P '^[0\t]*(1[0\t]*){5,}[0\t]*$' countme # Match >=5
1   0   0   1   0   1   1   0   1
1   1   0   1   0   1   0   1   1
1   1   1   1   1   1   1   1   1
+2

, 1:

grep '^[^1]*\(1[^1]*\)\{5,5\}[^1]*$'

, , :

grep '\(1[^1]*\)\{5,\}'

(\{n,m\}) . , , .

, , , 1, 1 s 1 . , 1: [^1]*. .

+2

Do

sed -nE '/^([^1]*1[^1]*){5}$/p' your_file

5

sed -nE '/^([^1]*1[^1]*){5,}$/p' your_file

5 .


: GNU sed -E man-, . -E , , Mac OSX.

+1

perl

$ perl -ane 'print if (grep {$_==1} @F) == 5' ip.txt 
1   0   0   1   0   1   1   0   1

$ perl -ane 'print if (grep {$_==1} @F) >= 5' ip.txt 
1   0   0   1   0   1   1   0   1
1   1   0   1   0   1   0   1   1
1   1   1   1   1   1   1   1   1
  • -a, @F
  • grep {$_==1} @Freturns an array with elements from the array @Fthat are exactly equal1
  • (grep {$_==1} @F) == 5 in a scalar context, the comparison will be based on the number of elements in the array
  • For more information on -aneoptions, see http://perldoc.perl.org/perlrun.html#Command-Switches .
+1
source

All Articles