Solución:
Usar
mongostat | awk -F ' *' '$19 ~ /^[0-9]+$/ { print "Number of connections: " $19 }'
$19 ~ /^[0-9]+$/
comprueba si $19
coincide con la expresión regular ^[0-9]+$
(es decir, si solo consta de dígitos), y la acción asociada solo se ejecuta si este es el caso.
Por cierto, ahora que lo pienso, el separador de campo especial probablemente sea innecesario. El separador de campo predeterminado de awk
es cualquier secuencia de espacios en blanco, así que a menos que mongostat
utiliza una combinación extraña de pestañas y espacios,
mongostat | awk '$19 ~ /^[0-9]+$/ { print "Number of connections: " $19 }'
debería funcionar bien.
Compruebe si este campo está formado solo por dígitos haciéndolo coincidir con la expresión regular ^[0-9]+$
:
$19~/^[0-9]+$/
^
significa comienzo de cadena y $
para el final, por lo que estamos comprobando si consta de dígitos desde el principio hasta el final. Con +
hacemos que coincida con al menos un dígito, de lo contrario, un campo vacío también coincidiría (por lo que un archivo con menos campos siempre coincidiría).
Todos juntos:
mongostat | awk 'BEGIN{FS=" *"} $19~/^[0-9]+$/ {print "Number of connections: "$19}'
Tienes que tener mucho cuidado aquí. La respuesta no es tan simple como imagina:
- un número entero tiene un signo, por lo que debe tenerlo en cuenta en sus pruebas. Entonces los enteros
-123
y+123
no se reconocerán como números enteros en las pruebas propuestas anteriormente. - awk convierte de forma flexible los tipos de variables de flotantes (números) a cadenas y viceversa. La conversión a cadenas se realiza usando
sprintf
. Si el flotante representa un número entero, use el formato%d
de lo contrario usa el formatoCONVFMT
(defecto%.6g
). Algunas explicaciones más detalladas se encuentran al final de esta publicación. Entonces, verificar si un número es un número entero o si una cadena es un número entero son dos cosas diferentes.
Entonces, cuando usa una expresión regular para probar si un número es un entero, funcionará perfectamente si su variable todavía se considera una cadena (como un campo sin procesar). Sin embargo, si su variable es un número, awk primero convertirá el número en una cadena antes de realizar la prueba de expresión regular y, como tal, esto puede fallar:
is_integer(x) { x ~ /^[-+]?[0-9]+$/ }
BEGIN { n=split("+0 -123 +123.0 1.0000001",a)
for(i=1;i<=n;++i) print a[i],is_integer(a[i]), is_integer(a[i]+0), a[i]+0
}
que salidas:
+0 1 1 0
-123 1 1 -123
+123.0 0 1 123 << QUESTIONABLE
1.0000001 0 1 1 << FAIL
^ ^
test test
as string as number
Como puede ver, el último caso falló porque “% .6g” convierte 1.0000001
en la cuerda 1
y esto se hace porque usamos operaciones de cadena.
Una solución más genérica para validar si una variable representa un número entero sería la siguiente:
function is_number(x) { return x+0 == x }
function is_string(x) { return ! is_number(x) }
function is_float(x) { return x+0 == x && int(x) != x }
function is_integer(x) { return x+0 == x && int(x) == x }
BEGIN { n=split( "0 +0 -0 123 +123 -123 0.0 +0.0 -0.0 123.0 +123.0 -123.0 1.23 1.0000001 -1.23E01 123ABD STRING",a)
for(i=1;i<=n;++i) {
print a[i], is_number(a[i]), is_float(a[i]), is_integer(a[i]),
a[i]+0, is_number(a[i]+0), is_float(a[i]+0), is_integer(a[i]+0)
}
}
Este método todavía tiene problemas para reconocer 123.0
como flotante, pero eso se debe a que awk solo conoce números de coma flotante.
Un valor numérico que es exactamente igual al valor de un número entero (ver Conceptos Derivados de la Norma ISO C) se convertirá en una cadena por el equivalente de una llamada al
sprintf
función (ver Funciones de cadena) con la cadena"%d"
como elfmt
argumento y el valor numérico que se convierte como el primer y únicoexpr
argumento. Cualquier otro valor numérico se convertirá en una cadena mediante el equivalente a una llamada alsprintf
función con el valor de la variableCONVFMT
como elfmt
argumento y el valor numérico que se convierte como el primer y únicoexpr
argumento. El resultado de la conversión no se especifica si el valor deCONVFMT
no es una especificación de formato de punto flotante. Este volumen de POSIX.1-2017 no especifica conversiones explícitas entre números y cadenas. Una aplicación puede forzar que una expresión sea tratada como un número agregando cero, o puede forzar que sea tratada como una cadena concatenando la cadena nula (""
) a ella.fuente: Estándar Awk Posix