Saltar al contenido

Compruebe si un campo es un número entero en awk

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 formato CONVFMT (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 el fmt argumento y el valor numérico que se convierte como el primer y único expr argumento. Cualquier otro valor numérico se convertirá en una cadena mediante el equivalente a una llamada al sprintf función con el valor de la variable CONVFMT como el fmt argumento y el valor numérico que se convierte como el primer y único expr argumento. El resultado de la conversión no se especifica si el valor de CONVFMT 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

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *