Você pode usar awk
da seguinte maneira para evitar a repetição da verificação de 7 colunas consecutivas usando um sinalizador para incrementar quando todas atenderem à condição ou redefini-la quando contrário.
awk '{c=0; split($0,arr,/ +/);
for(x in arr) if(arr[x]<10 && arr[x]>=0) {
if(++c==7){ print $0; next } }else{c=0} }' infile
Aqui usamos função dividida do awk « split(string, array [, fieldsep [, seps ] ])
» para dividir as linhas (O $0
representa a linha inteira em awk
) na matriz denominada arr
separada por um ou mais espaços.
Em seguida, dê um loop nos elementos da matriz e verifique se seu valor está entre 10 e 0, depois incremente um sinalizador chamado c
e imprima a linha se ela for atingida para 7 (significa que 7 elementos consecutivos (colunas) atendem à condição); Caso contrário, descanse a bandeira com 0.
Ou fazendo o mesmo sem dividir a linha em array.
awk '{c=0; for(i=1;i<=NF;i++) if($i<10 && $i>=0) {
if(++c==7){ print $0; next } }else{c=0} }' infile
No seu caso, como você vai filtrar a partir da coluna 4 até o final, você precisará de algo como. O NF
representa o número de campos / colunas em cada linha e continua em awk
.
$ time awk '{c=0; for(i=4;i<=NF;i++) if($i<10 && $i>=0) {
if(++c==7) {print $0; next} }else{c=0} }' infile
real 0m0.317s
user 0m0.156s
sys 0m0.172s
Ou no modo regex, novamente aplicado no seu arquivo original , onde ele contém apenas ponto flutuante números, você pode usar abaixo o comando grep
que é mais eficiente e ~ 6 vezes mais rápido que awk
(Onde usado com -P
flag, veja Grep -E, Sed -E - baixo desempenho quando '[x] {1,9999}" é usado, mas por quê? ), mas considerando a flexibilidade de awk
solução, como você pode alterar os intervalos + funcionará se Integer / Float / mixed de ambos os números.
$ time grep -P '([^\d]\d\.\d[^\d]){7}' infile
real 0m0.060s
user 0m0.016s
sys 0m0.031s
Ou de outra forma:
$ time grep -P '(\s+\d\.\d\s+){7}' infile
real 0m0.057s
user 0m0.000s
sys 0m0.031s
Ou compatibilidade em grep
, sed
ou awk
:
$ time grep -E '([^0-9][0-9]\.[0-9][^0-9]){7}' infile
real 0m0.419s
user 0m0.375s
sys 0m0.063s
$ time sed -En '/([^0-9][0-9]\.[0-9][^0-9]){7}/p' infile
real 0m0.367s
user 0m0.172s
sys 0m0.203s
$ time awk '/([^0-9][0-9]\.[0-9][^0-9]){7}/' infile
real 0m0.361s
user 0m0.219s
sys 0m0.172s