He probado tantas variaciones pero ninguna parece funcionar, no tengo idea de lo que no entiendo.
El último que probé es (\<[[:digit:]]+\>.*){4,} . Pero ni siquiera encuentra líneas como 123 123 123 123 . Las líneas de entrada pueden ser cualquier cosa (incluso como hello 123 my 1 name 2 is 3 ).
No lo especifiqué, lo siento, pero lo que quise decir es: la línea "123 a2" tiene 1 número, la línea "1 2 3 45" tiene 4 números.
Con sus muestras mostradas, intente seguir el código awk . NO necesitamos usar bucle aquí. Este código awk está escrito y probado en GNU awk .
awk -v FPAT='(^|[[:space:]]+)[0-9]+([[:space:]]+|$)' 'NF>3' Input_fileExplicación: agregando una explicación detallada de lo anterior.
awk llamada FPAT para permitir que regex haga separadores de campo.(^|[[:space:]]+)[0-9]+([[:space:]]+|$) para hacer coincidir espacios iniciales seguidos de dígitos O dígitos seguidos de espacios o el final de la línea.awk , verifique la condición NF>3 , lo que significa que si el número de campos es mayor que 3, imprima esa línea.Parece que hay algún problema con la cuantificación del patrón en su comando grep . Si el primer número tiene más de un dígito y los demás contienen solo uno, su expresión regular funciona. De lo contrario, no lo hará, vea los resultados de las pruebas :
#!/bin/bash s="123 1 2 3 - works, the first number is two+ digits, the rest are one digits 1 2 3 45 - does not work, the first number is one-digit 14 2 3 4 - works 123 a2 - not output as expected as there is just one number 12 and one 1 more and 23 and 6 and some more 3546 hello 123 my 1 name 2 is 3 - output fine since the first number is three-digit and the rest are one digit" grep -E '(\<[[:digit:]]+\>.*){4,}' <<< "$s"Producción:
123 1 2 3 - works, the first number is two+ digits, the rest are one digits 14 2 3 4 - works hello 123 my 1 name 2 is 3 - output fine since the first number is three-digit and the rest are one digit Si lo reescribes sin {4,} funciona:
grep -E '\<[0-9]+\>.*\<[0-9]+\>.*\<[0-9]+\>.*\<[0-9]+\>' fileVea esta demostración en línea .
También puede usar este awk en cualquier entorno:
awk '{cnt=0; for (i=1; i<=NF; ++i) { if ($i ~ /^[0-9]+$/) { cnt++ } } }cnt>3' fileVea la demostración en línea . Detalles :
cnt=0 - establece la variable del contador cnt en 0for (i=1; i<=NF; ++i) {...} - iterar sobre todos los campos en el registro actual (=línea)if ($i ~ /^[0-9]+$/) { cnt++ } } - si el campo está hecho de dígitos incrementa cntcnt>3 : si cnt es mayor que 3 , imprime el registro encontrado.Vea la demostración en línea :
#!/bin/bash s="123 123 123 123 1 2 3 45 1 3 5 hello 123 my 1 name 2 is 3" awk '{cnt=0; for (i=1; i<=NF; ++i) { if ($i ~ /^[0-9]+$/) { cnt++ } } }cnt>3' <<< "$s"Producción:
123 123 123 123 1 2 3 45 hello 123 my 1 name 2 is 3