steeldriver has already provided an awk solution. Here's a perl version (using an array slice rather than a for loop):
$ perl -lane 'print if ($.==1 || grep ($_ >= 2, @F) == $#F)' input.txt
name v1 v2 v3 v4
g2 10 3 5 2.3
g3 7 2.5 2.8 3.9
This prints only the first (header) line and lines where all numeric fields have a value greater than or equal to 2. (non-numeric fields like
g2 will evaluate to
grep() function is similar in concept, but not exactly the same as the
grep command-line program.
grep(expression,array) runs the expression in its first argument (e.g.
$_ >= 2) against every element of an array (e.g.
@F), and returns an array consisting of every element where the result was true.
In a scalar context (such as a numeric comparison against an integer), it returns the number of times the expression was true, instead of an array. This is what we are doing here with
== $#F, to test equivalence with
$#F (the number of elements in array
The expression can be a simple test as used in this example, or a code block containing any perl code. It can also optionally modify each element. e.g.
@new = grep(s/foo/bar/g, @old) would populate @new with all elements from @old which were successfully modified (i.e. thost that contained at least one "foo". all of which were changed to "bar"). See
perldoc -f grep for details.