Tomar números de un ping con .bat

Espero me puedas ayudar como puedo tomar los resultados de un ping, solo los números de paquetes enviados, recibidos, perdidos y promedio de timepos, he intentaod con find y solo me trae la línea completa y con skip pero en consola me muestra unas líneas y en > archivo.txt solo imprime la ultima línea

1 respuesta

Respuesta
1

Tu consulta es un poco inconcreta de manera que voy a interpretarla un poco a mi manera. Para empezar imagino que vas a hacer ping a una lista de direcciones IP que supondré guardadas en un archivo de nombre DIRIP.TXT con una IP por línea del archivo. El número de pings de cada intento se guarda en la variable NP a la que le he asignado el valor 5. El resultado de cada PING lo guardo en un archivo temporal RESPING.TXT y lo analizo en el BAT para extraer la información que indicas. Para cada PING saco una línea en el archivo ESTPING.CSV con el formato IP;TiempoMedio;PaqEnviados;PaqRecibidos;PaqPerdidos. He elegido esta forma de salida porque se puede abrir directamente en Excel. Si se quisiera otro formato solo habría que retocar la parte de la salida. Cuando el ping no tiene éxito utilizo para el TiempoMedio el carácter ASCII 255 (ÿ) que en MSDOS se presenta como un espacio y el comando ECHO no lo elimina.

Este es el BAT que he preparado:

@echo off
Setlocal EnableDelayedExpansion
del /q estping.csv > nul 2>&1
set np=5
set /a lin=5 + %np%
echo IP;TMed(ms);Env;Rec;Per>>estping.csv
for /f "tokens=*" %%a in (dirip.txt) do (
   ping -n %np% %%a > resping.txt
   set tm=ÿ
   for /f "skip=%lin% tokens=1,4,7,9,10,*" %%b in (resping.txt) do (
      if "%%b"=="Paquetes:" (
         set env=%%c&set env=!env:,=!
         set rec=%%d&set rec=!rec:,=!
         set per=%%f
      )
      if "%%b"=="M¡nimo" set tm=%%e&set tm=!tm:ms=!
   )
   if not "!tm!"=="ÿ" set /a tm=!tm!
   echo %%a;!tm!;!env!;!rec!;!per!>>estping.csv
)

Lo he probado en Windows XP. Dime si te sirve.

En Windows10 hay que cambiar:

set /a lin=5 + %np%

por:

set /a lin=4 + %np%

¿Primero eres un Crack me funciona perfecto ya estoy añadiendo medio mínimo de ms y si genial esta super me funciona de maravilla . Una pregunta al alterar la cantidad de %%np a mayor puede alterar el skip?

Sí, pero no. Altera el skip, claro, pero ya está contemplado en el Bat. Si te fijas el skip se hace con el valor de la variable LIN y esta se obtiene a partir de NP y de una cantidad fija, que, según puedes ver en mi última aclaración, depende de la versión del sistema operativo, pero no del número de intentos del ping..

Me puedes explicar como funciona el token y el skip en este bach,

Y como toman los valores numéricos

Supongo que sabes que si tecleas FOR /? en una ventana CMD/Símbolo del sistema te cuenta todo lo relacionado con el comando FOR, y por tanto también lo que significan los parámetros que se usan en él. Pero debo reconocer que no siempre se entiende bien esa "ayuda". De modo que no "escurriré el bulto" (no sé si conoces este modismo si no vives en España) e intentaré explicártelos.

Primero el skip. Indica el número de líneas que se deben saltar del comienzo del "archivo" (o lista equivalente si en lugar de un archivo se pone un comando que genera una lista dentro de los paréntesis que siguen al IN del FOR en cuestión). Si analizamos el FOR que usa SKIP:

   for /f "skip=%lin% tokens=1,4,7,9,10,*" %%b in (resping.txt) do (

vemos que el FOR se aplica al archivo RESPING.TXT y que se le dice que se salte el número de líneas del comienzo indicado en la variable LIN. Esto nos debe situar en la línea que dice:

    Paquetes: enviados = 5, recibidos = 5, perdidos = 0

Ahora vamos al TOKENS. Aquí le decimos que de los campos que tiene esa línea vamos a asignar a la variable %%b, el primero, a la %%c el cuarto, a la %%d el séptimo, a la %%e el noveno, a la %%f el décimo y a %%g lo que sobre de la línea (por eso el * final). ¿Y cuál es el separador de campos? Por defecto es espacio o tabulador, pero eso se puede controlar con el parámetro DELIMS. Como no se explicita ese parámetro estoy usando el valor por defecto. De modo que el primer campo de esa línea es "Paquetes:", el segundo "enviados", el tercero "=", el cuarto "5," el quinto "recibidos", el sexto "=", el séptimo "5," el octavo "perdidos", el noveno "=", el décimo "0" y lo restante lo que quede de la línea (en este caso nada).

Entonces, para este caso concreto de RESPING.TXT en el análisis de la primera línea tratada tendríamos:

%%b=Paquetes:   (el primer campo, tokens 1)

%%c=5,                (el cuarto campo, tokens 4)

%%d=5,                (el séptimo campo, tokens 7)

%%e==                (el noveno campo, tokens 9)

%%f=0                (el décimo campo, tokens 10)

A partir de aquí seguimos tratando las restantes líneas de RESPING.TXT. Las siguientes en mi ejemplo serían:

 (0% Perdidos),
Tiempos aproximados de ida y vuelta en milisegundos:
    M¡nimo = 43ms, M ximo = 43ms, Media = 43ms

Las dos siguientes no nos interesan, aunque también cargarían las variables, pero los IF del bucle solo se fijan en las que tienen como valor de %%b "Paquetes:" o "M¡nimo". En la última vemos que %%e=43ms.

Luego hay que limpiar lo que no queremos de las variables, por ejemplo las comas de "5," o los "ms" de "43ms". Eso es lo que se hace en:

         set env=%%c&set env=!env:,=!
         set rec=%%d&set rec=!rec:,=!
         set tm=%%e&set tm=!tm:ms=!

Y creo que con esto ya tienes bastante trabajo por hoy. Pero puedes seguir preguntando, si quieres.

Te cuento que estoy aprendiendo mucho, ya estoy preparando más preguntas y por el momento un gran saludo desde Colombia-Medellin

Me alegro mucho de servirte de ayuda. Pregunta lo que quieras, que ya veremos si puedo contestar ;-)

una pregunta por que cunado imprimo los datos en el navegador por que salen malos y en consola salen perfectos

No entiendo bien que significa "imprimir los datos en el navegador". ¿Te refieres a los datos que genera el bat del que estamos hablando? ¿Qué datos salen "malos"? ¿Qué navegador utilizas?

chrome e imprimir es hacer un type de cmd (consola) en el navegador y aprovecho para agradecerte nuevamente ya tengo casi todos los conceptos muy claros, ¿me gustaría que profundices en el carácter ASCII 255 (ÿ) y su función en el código y quiero saber por que cuando ejecuto el .bat desde php si nio obtengo respuesta me dice que el tiempo de espera en el navegador es excedido?

Hola de nuevo como puedo cambiar ese variable tm=ÿ para que me de 0 por que le estoy diciendo que si no hay timepo medio me muestre un "0" y lo mismo con el resto de los tiempos max, min que muestre "0" ya que le cambie el valor a  "0" pero en min y en max no lo reconoce osea me lee otra columna 


                    

y no logro entender como funciona !tm!

Hola asi llev el .bat 

@echo off
Setlocal EnableDelayedExpansion
del /q estping.csv > nul 2>&1
set np=5
set bytes=256
set /a lin=4 + %np%
echo IP;Env;Rec;Per;TMed(ms);TMax(ms);TMin(ms)>>estping.csv
echo %date% >>resping.txt ^%TIME%>>resping.txt
for /f "tokens=*" %%a in (dirip.txt) do (
   ping -n %np% -l %bytes% %%a >> resping.txt
   set tm=0
   for /f "skip=%lin% tokens=1,3,4,6,7,9,10,*" %%b in (resping.txt) do (
      if "%%b"=="Paquetes:" (
         set env=%%d&set env=!env:,=!
         set rec=%%f&set rec=!rec:,=!
         set per=%%h
      )
      if "%%b"=="M¡nimo" set tm=%%g&set tm=!tm:ms=!
            set tma=%%e&set tma=!tma:ms,=!
            set tmi=%%c&set tmi=!tmi:ms,=!
   )
   if not "!tm!"=="0" set /a tm=!tm!
   echo %%a;!env!;!rec!;!per!;!tm!;!tma!;!tmi!>>estping.csv
)
type estping.csv

adicione esto al codigo

set tm=0
set tma=0
set tma=0

if "%%b"=="M¡nimo" set tm=%%e&set tm=!tm:ms=!
                   set tmi=%%e&set tmi=!tmi:ms=!
                   set tma=%%e&set tma=!tma:ms=!

y al hacer esto me arroja es "ms,=" en ves de 0 que puedo hacer ya que creo que me esta leyendo el ping anterior en cuanto al tema del tiempo que me aconsejas mi archivo "dirip.txt" tiene 3 ips

No uso Chrome y no tenía ni idea de que desde un navegador se podían lanzar comandos de CMD. ¿Se escriben directamente en la casilla de las URLs o es alguna facilidad especial de Chrome? En todo caso, ¿en qué sentido son malos los datos que te salen de esa manera? ¿Puedes copiarme algún caso?

En cuánto al carácter ASCII 255 (ÿ para el juego de caracteres Unicode) tiene la "ventaja" de presentarse como un espacio en una ventana CMD pero sin el inconveniente que los espacios (ASCII 32) pueden ocasionar al lanzar un comando ECHO por ejemplo. Lo uso cuando un valor "espacio" o nulo me da algún problema. Asignar un valor de cero al tiempo de respuesta a un ping sin respuesta no me parece muy razonable, porque si haces ping a localhost te da realmente un tiempo de respuesta de 0 ms, pero es un verdadero tiempo de respuesta (seguramente son microsegundos, asimilables a 0 ms). Por eso decidí que era preferible que saliera como "espacio", pero si ponía el espacio estándar me daba problemas. Pero si quieres que salga 0 creo que tendrás que forzar a que sea un cero numérico, es decir con set /a tm=0. Si quieres pásame lo que estás probando para que pruebe yo también. En realidad estas cosas no me las sé hasta que las pruebo, y luego se me olvidan.

En cuanto a ! Tm!: La variable de entorno EnableDelayedExpansion habilita lo que los desarrolladores (y traductores) de la shell cmd de Microsoft llaman expansión retardada. Puedes ver lo que cuentan ellos si tecleas SET /? en una ventana CMD.

Concretamente, si quieres que dentro de un bucle FOR los cambios en el valor de una variable tengan efecto, debes usar "setlocal EnableDelayedExpansion" y recuperar el valor de la variable invocándolo entre "!!" en lugar de hacerlo entre "%%". Como las variables que usamos las cargamos dentro del bucle y luego las modificamos, bien para quitar las comas o los "ms", hay que hacerlo de esta manera.

¡Gracias! Y si mira en php lo que hago es esto
<?php
a=shell_exec ( .bat );

echo (a);

Pero cuando los datos vienen completos me da perfecto pero si los datos no llegan con la línea que inicie por "M!nimo" me da error, osea el tiempo medio lee el dato anterior y el máximo y mínimo me trae un ms=

Prueba con esto:

@echo off
Setlocal EnableDelayedExpansion
del /q estping.csv > nul 2>&1
set np=5
set bytes=256
set /a lin=4 + %np%
echo IP;Env;Rec;Per;TMed(ms);TMax(ms);TMin(ms)>>estping.csv
echo %date% >>resping.txt ^%TIME%>>resping.txt
for /f "tokens=*" %%a in (dirip.txt) do (
   ping -n %np% -l %bytes% %%a >> resping.txt
   set tm=0
   set tma=0
   set tmi=0
   for /f "skip=%lin% tokens=1,3,4,6,7,9,10,*" %%b in (resping.txt) do (
      if "%%b"=="Paquetes:" (
         set env=%%d&set env=!env:,=!
         set rec=%%f&set rec=!rec:,=!
         set per=%%h&set per=!per:~0,-1!
      )
      if "%%b"=="M¡nimo" (
         set tma=%%e&set tma=!tma:ms,=!
         set tmi=%%c&set tmi=!tmi:ms,=!
         set tm=%%g&set tm=!tm:ms=!&set tm=!tm:~0,-1!
      )
   )
   echo %%a;!env!;!rec!;!per!;!tm!;!tma!;!tmi!>>estping.csv
)
type estping.csv

Aunque no entiendo la línea del echo %date%... Tengo un poco de prisa. A ver si mañana te puedo explicar los añadidos a las variables "per" y "tm". Tienen que ver con el cambio de línea que llevan asociado.

me ingresa la fecha y la hora en el resping.txt

Creía que te había respondido esta mañana pero no veo la respuesta ahora. Así que voy a intentar reproducir lo que te dije. No es la primera vez que me ocurre y siempre me propongo copiar el texto antes de enviarlo por si acaso pero al final no lo hago casi nunca, y me fastidia mucho tener que volver a pensar lo ya pensado, además de que puede que se me escape algo. Además alguna vez después de volver a responder reaparece la respuesta original, pero no puedo contar con ello.

Decía que en mi "diseño" original es RESPING.TXT es un archivo temporal que guarda la respuesta a cada ping individual y que usarlo como una especie de log de todas las respuestas, de todas las ejecuciones del bat, invalida los resultados. Esta mañana no era muy consciente de hasta que punto los invalida y pensé que solo en los casos en que el destinatario del ping no contestaba podría producir resultados erróneos. Eso era porque no caí en la cuenta de que la forma en que lo has modificado hace que las nuevas respuestas se añadan al final. En resumen que así no funciona bien, como puedes comprobar si contrastas lo que aparece en ese RESPING.TXT con funciones de log con lo que se ofrece en el ESTPING. CSV tras una ejecución concreta del bat.
Si quieres un log hay que incorporar un RESPING.LOG (por ejemplo) al que se vayan añadiendo los nuevos resultados. También decía que me había dado cuenta de que el control mediante IF de las líneas a analizar para cargar las variables hacía innecesario el parámetro SKIP del FOR.

Te ofrezco ahora la versión del bat que debe ajustarse a tus necesidades, incluyendo el asignar valores de cero a los tiempos para los ping que no obtienen respuesta, aunque, como decía más arriba, no me parece muy correcto darle un valor de cero a lo que más bien debería dársele un valor de infinito (o alguna otra opción, como "NP" de "no procede", por ejemplo):

@echo off
Setlocal EnableDelayedExpansion
del /q estping.csv > nul 2>&1
set np=5
set bytes=256
echo %date% %TIME%>>resping.log
echo IP;Env;Rec;Per;TMed(ms);TMax(ms);TMin(ms)>>estping.csv
for /f "tokens=*" %%a in (dirip.txt) do (
   ping -n %np% -l %bytes% %%a>resping.txt
   set tm=0
   set tma=0
   set tmi=0
   for /f "tokens=1,3,4,6,7,9,10,*" %%b in (resping.txt) do (
      if "%%b"=="Paquetes:" (
         set env=%%d&set env=!env:,=!
         set rec=%%f&set rec=!rec:,=!
         set per=%%h&set per=!per:~0,-1!
      )
      if "%%b"=="M¡nimo" (
         set tma=%%e&set tma=!tma:ms,=!
         set tmi=%%c&set tmi=!tmi:ms,=!
         set tm=%%g&set tm=!tm:ms=!&set tm=!tm:~0,-1!
      )
   )
   echo %%a;!env!;!rec!;!per!;!tm!;!tma!;!tmi!>>estping.csv
   copy /a resping.log + resping.txt resping.log > nul
)
type estping.csv

Nuevamente mil gracias, ¿sin tener con que pagarte y segundo es nuevo para mi el tema de los .log pero ya estoy estudiando si me ayudas a aprender seria genial estoy manegando terminal de cmd y linux ese msmo código lo engoque pasar a linux .sh y es bueno especializarse en manejo de terminales? Me gustaría saber si me puedes enseñar más, que me recomiendas con que puedo seguir; actualmente hago las practicas como técnico en desarrollo de software. Y estoy haciendo cosas sorprendestes para ellos con lo que me enseñas nuevamente muy pero muy agradecido. Haré una pruebas con el código que me diste yo modifique el anterior porque cuando me dama resultados en el tiempo medio si era 20 me borraba el 0 y estoy de acuerdo con tigo voy a remplazar el 0 por NP quedo atento y espero usted pueda ser mi mentor. Por el momento lo que necesites de colombia de medellín con gusto y si vas a pasar por aquí cuentas con un amigo

Se suele llamar LOG a un tipo de archivos, normalmente de "texto plano" (es decir, de los que pueden abrirse con el Notepad/Bloc de notas), donde se registra todo lo ocurrido en las sucesivas ejecuciones de un programa. Se le suele poner extensión LOG, pero es, simplemente, una forma de hablar, no es que haya una "ciencia" de los log. En Linux no tengo mucha experiencia pero las shells de Linux son bastante más potentes y versátiles que las de Windows/MSDOS. Y hablando de shells de Windows/MSDOS existe una muchísimo más potente que esta tradicional con la que estamos trabajando que se llama POWERSHELL. Tampoco tengo mucha experiencia con ella pero sí la suficiente como para poder decir que es muy recomendable y que, hasta ahora, me ha resuelto todos los problemas que no conseguía resolver con la tradicional. Y puedes contar conmigo para lo que quieras.

¿Nuevamente hola es posible almacenar la información de resping.txt en una variable y extraer los datos como se le extraen? ¿Osea qué no lleguen a guardace en el .txt si no en una variable?

No. Esa es una pregunta muy vieja en este terreno y el que la respuesta sea no (hasta donde yo sé, pero creo que hay bastantes garantías de que esté en lo cierto) explica lo mucho que se usa el FOR /F en casi todos los bat. Incluso cuando la respuesta es una sola letra no hay manera de almacenarla en una variable.

No obstante se podría prescindir del almacenamiento de los resultados del ping en un TXT tratando directamente la respuesta en el FOR correspondiente. Esto, lógicamente, supondría prescindir del log. Quedaría algo así:

del /q estping.csv > nul 2>&1
set np=5
set bytes=256
echo IP;Env;Rec;Per;TMed(ms);TMax(ms);TMin(ms)>>estping.csv
for /f "tokens=*" %%a in (dirip.txt) do (
   set tm=ND
   set tma=ND
   set tmi=ND
   for /f "tokens=1,3,4,6,7,9,10,*" %%b in ('ping -n %np% -l %bytes% %%a') do (
      if "%%b"=="Paquetes:" (
         set env=%%d&set env=!env:,=!
         set rec=%%f&set rec=!rec:,=!
         set per=%%h
      )
      if "%%b"=="M¡nimo" (
         set tma=%%e&set tma=!tma:ms,=!
         set tmi=%%c&set tmi=!tmi:ms,=!
         set tm=%%g&set tm=!tm:ms=!
      )
   )
   echo %%a;!env!;!rec!;!per!;!tm!;!tma!;!tmi!>>estping.csv
)
type estping.csv

Ahora, no sé muy bien por qué, no deben usarse las limpiezas que se hacían para el final de línea en las variables PER y TM.

Es evidente que estoy aprendiendo mucho y creo que el tema lo daría por terminado, si me puedes indicar sobre algo que sea un poco difícil de manejar en cmd te agradecería que me digas que debo estudiar más o existe más en el for o en if

Para mí es impensable aprender este tipo de cosas si no es sobre algo concreto. De modo que no puedo aconsejarte gran cosa. El "programa" bat más complejo que he hecho nunca es el que aparece en: Alternativa en Batch para copiar imágenes de disco SD/USB pero a veces hay preguntas cortas que suponen un verdadero esfuerzo.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas