Programación BATCH Avanzada
Programación BATCH Avanzada
Temario. 1.- Variables y Argumentos. 2.- Imprimir caracteres de comandos. 3.- Algunas otras variables de Entorno. 4.- IF 5.- FOR 6.- Funciones 7.- Includes 8.- Misc 9.- EOF
Variables y Argumentos El manejo de variables en batch es muy flexible y nos permite hacer desde operaciones matemticas, hasta seleccionar ciertas partes de una variable, as como reemplazar cadenas de texto, obtener archivos y sus propiedades, la fecha, hora, generar nmeros aleatorios, etc. Los argumentos que recibe un batch son recibidos de la siguiente forma: batch argumento1 dos tres har que: %0 = batch %1 = argumento1 %2 = dos %3 = tres en %0 se guardar el nombre del archivo. Podemos borrar el contenido de un parmetro con el comando shift: Cdigo: @echo off echo %0 %1 %2 %3 shift /1 echo %0 %1 %2 %3 al llamar: Cdigo: C:\Documents and Settings\Administrador\tempcurso>astring 123 456 789 astring 123 456 789 astring 456 789 shift borr el primer argumento. Tambin contamos con los siguientes modificadores para los archivos: Cdigo: %~f1 %~d1 %~p1 %~n1 %~x1 %~s1 %~a1 %~t1 %~z1 regresa regresa regresa regresa regresa regresa regresa regresa regresa la ruta y el archivo de %1. la letra de la unidad de %1. solo la ruta del archivo %1. solo el nombre de archivo %1. solo la extensin del archivo %1. solo la ruta, con directorios, con nombres cortos del archivo %1. los atributos del archivo. la hora/fecha del archivo %1 el tamao del archivo %1.
por ejemplo: en un directorio donde tenemos: Cdigo: C:\Documents and Settings\Administrador\tempcurso>dir El volumen de la unidad C no tiene etiqueta. El nmero de serie del volumen es: A057-553B Directorio de C:\Documents and Settings\Administrador\tempcurso 24/07/2006 24/07/2006 24/07/2006 12:25a <DIR> 12:25a <DIR> 12:25a 6 1 archivos 2 dirs 401,715,161,088 . .. archivo.txt 6 bytes bytes libres
este batch: Cdigo: @echo off echo Ruta al archivo: %~f1 echo Disco: %~d1 echo Solo ruta: %~p1 echo Nombre: %~n1 echo Extensin: %~x1 echo Ruta Corta: %~s1 echo Atributos: %~a1 echo Fecha: %~t1 echo Tamao: %~z1 llamndolo analiza.bat, saca el siguiente resultado: Cdigo: C:\Documents and Settings\Administrador\tempcurso>analiza archivo.txt Ruta al archivo: C:\Documents and Settings\Administrador\tempcurso\archivo.txt Disco: C: Solo ruta: \Documents and Settings\Administrador\tempcurso\ Nombre: archivo Extensin: .txt Ruta Corta: C:\DOCUME~1\ADMINI~1\TEMPCU~1\archivo.txt Atributos: --a-----Fecha: 24/07/06 12:25a Tamao: 6 Tambin podemos usar varias propiedades, por ejemplo, este cdigo: Cdigo: @echo off echo %~anxt1 saca este resultado: Cdigo: C:\Documents and Settings\Administrador\tempcurso>analiza archivo.txt --a------ 24/07/06 12:25a archivo.txt
Si lo que recibimos no es un archivo sino una cadena de texto, que contiene ms de una palabra, se debe poner entre comillas, algo as: astring "parmetro de varias letras" al obtenerlo, en %1, lo recibimos con comillas, pero si usamos: Cdigo: @echo off echo Con Comillas: %1 echo Sin Comillas: %~1 saca este resultado: Cdigo: C:\Documents and Settings\Administrador\tempcurso>astring "parmetro de varias letras" Con Comillas: "parmetro de varias letras" Sin Comillas: parmetro de varias letras Y por ejemplo, si queremos obtener todos los argumentos, se usa: %* es decir: Cdigo: @echo off echo Argumentos: %* al ejecutar: astring parmetro de varias letras nos regresa: Cdigo: C:\Documents and Settings\Administrador\tempcurso>astring parmetro de varias letras Argumentos: parmetro de varias letras
Para asignar a una variable el valor de algo escrito por el usuario puedes usar: set /P variable= por ejemplo: Cdigo: @echo off echo Cmo te llamas? set /P miva= echo T te llamas %miva% har algo as: Cdigo: C:\Documents and Settings\Administrador\tempcurso>astring Como te llamas? Juan T te llamas Juan
Subcadenas Ahora, si por ejemplo queremos hacer algo como obtener las ltimas 3 letras del nombre: Cdigo: @echo off echo Escribe tu Nombre set /P NOM= echo %NOM:~-3% Aqu lo que estamos haciendo en la ltima lnea: %NOM:~-3% Obtendr los ltimos 3 caracteres, como si se tratara de la funcin substring. Por ejemplo, esto: %NOM:~1,3% Obtendr del segundo al cuarto carcter. (empieza desde 0, recuerda) SET STRING=[ABCDEFG] SET STRING=%STRING:[=% SET STRING=%STRING:]=% ECHO String: %STRING% Mostrar String: ABCDEFG SET STRING=[ABCDEFG] SET STRING=%STRING:[=(% SET STRING=%STRING:]=)% ECHO String: %STRING% Mostrar String: (ABCDEFG) SET STRING=[ABCDEFG] SET STRING=%STRING:~1,7% ECHO String: %STRING% Mostrar String: ABCDEFG
Declaramos ABC=abcdefghijklmnopqrstuvwxyz %ABC:~desplazamiento,longitud% %ABC:~6,5% (desplaza 6 caracteres y muestra 5 a partir del 6to) ghijk %ABC:~10% (desplaza 10 posiciones y si no se especifica la longitud utiliza el resto de la cadena como longitud) klmnopqrstuvwxyz Si algn nmero (desplazamiento o longitud) es negativo, entonces el nmero usado es la longitud del valor de la variable de entorno agregado al desplazamiento o longitud especificados. %ABC:~-10% (muestra los 10 ltimos) qrstuvwxyz %ABC:~0,-10% (muestra todos menos los 10 ltimos caracteres) %ABC:~0,-2% (muestra todos menos los ltimos 2) abcdefghijklmnopqrstuvwx %ABC:~-2% (muestra los ltimos 2) yz %ABC:~3,-5% (muestra la cadena ABC quitando los 3 primeros y los 5 ltimos) defghijklmnopqrstu %ABC:~1% (muestra la cadena ABC completa menos el primer carcter) Si queramos obtener la fecha o la hora en 3 variables utilizando una sola lnea debamos hacer esto: set dia=%date:~0,2% & set mes=%date:~3,-5% & set ao=%date:~-4% Ahora: Obtener la fecha en 3 variables utilizando un solo set /a. set /a dia=%date:~0,2%,mes=%date:~3,-5%,ao=%date:~-4% Obtener la hora en 3 variables utilizando un solo set /a (se complica un poco ms). set /a hora=%time:~0,2%,min=%time:~3,-6%,a=%time:~6%,b=%time:~-2%,seg=a*100+b Para reemplazar cadenas, dentro de otra variable, es la siguiente sintaxis: Cdigo: @echo off echo Escribe una frase set /P FRA= echo %FRA:e=XXX% esto reemplazara las letras "e" por "XXX". Cmo sustituir, dentro de una string de caracteres, un substring por otro determinado? set variable=+ABC+123 Imaginemos que queremos cambiar TODOS los signos + por las letras "kf". En ese caso hacemos a continuacin: set variable=%variable:+=kf% En este caso, al ejecutar ahora un echo %variable% nos devolver: "kfABCkf123" En particular, nos puede servir para eliminar los caracteres de puntuacin de una variable sustituyndolas por nulos. Es decir: set variable=1.234.567 si hacemos ahora: set variable=%variable:.=% su contenido quedar como "1234567" por tanto, numrico puro y con el /a del punto 1) anterior podramos realizar operaciones matemticas
Para hacer clculos matemticos, se usa el modificado /A, de esta forma: Cdigo: @echo off set /A x=1 echo %x% set /A x=x*9 echo %x% tenemos las siguientes operaciones disponibles: Cdigo: () * / % + << >> & ^ | = *= /= %= += -= &= ^= |= <<= >>= , agrupar operadores aritmticos operadores aritmticos mays lgica AND XOR OR asignacin
- separador de expresin
Con este podemos usar nmeros hexadecimales de la siguiente forma: Cdigo: @echo off set /A x=2 echo %x% set /A x=x*0xff echo %x% al colocar 0x estamos especificando, que a continuacin se pondr un valor hexadecimal.
Imprimir caracteres sin usar comandos En las variables siempre usamos los signos % Cmo imprimes uno? Cdigo: @echo off set x=pru set pru=HOLA :: Esto imprimir el contenido de x echo %x% ::Esto imprimir la letra x echo x ::Esto imprimir %x% echo %%x%% ::Esto imprimir el valor de x entre %% echo %%%x%%% :: Lo mismo echo %pru% echo %%pru%% echo %%%pru%%% En resumen, si quieren imprimir el carcter %, deben colocarlo 2 veces.
Para otros caracteres, que ejecutan alguna accin en batch como: & | < > debes colocar este carcter antes:^ por ejemplo: Cdigo: echo <html><h1>Hola</h1></html> >index.html no funcionara, pero: Cdigo: echo ^<html^>^<h1^>Hola^</h1^>^</html^> >index.html dar: Cdigo: C:\Documents and Settings\Administrador\tempcurso>type index.html <html><h1>Hola</h1></html>
Algunas otras variables de entorno Tenemos otras variables de entorno que podran servir, adems de las comunes de ALLUSERSPROFILE y HOMEPATH, por ejemplo: Cdigo: @echo off echo Directorio Actual: %CD% echo Fecha: %DATE% echo Hora: %TIME% echo Numero Aleatorio: %RANDOM% dar como resultado: Cdigo: C:\Documents and Settings\Administrador\tempcurso>astring Directorio Actual: C:\Documents and Settings\Administrador\tempcurso Fecha: Lun 24/07/2006 Hora: 2:13:49.33 Numero Aleatorio: 24523 C:\Documents and Settings\Administrador\tempcurso>astring Directorio Actual: C:\Documents and Settings\Administrador\tempcurso Fecha: Lun 24/07/2006 Hora: 2:13:51.60 Numero Aleatorio: 3681 Otras instrucciones muy tiles, serian POPD y PUSHD, que sirven para guardar y regresar al directorio actual, por ejemplo: Cdigo: @echo off echo %CD% PUSHD \ echo %CD% POPD echo %CD% PUSHD funciona de la siguiente manera: Guarda el directorio actual., y va a la ruta especificada. POPD regresa al directorio guardado por PUSHD podemos usarlos uno dentro de otro, as:
Cdigo: @echo off echo %CD% PUSHD \ echo %CD% PUSHD %homepath% echo %CD% POPD echo %CD% POPD echo %CD%
IF If, reconoce varias situaciones: valores de error comparar cadenas existencia de archivos comparaciones matemticas como ya sabemos %ERRORLEVEL% almacena algunos valores de otras funciones. al hacer IF ERRORLEVEL 1 @echo ok ELSE @echo no estaramos preguntando si ERRORLEVEL es 1, si lo es imprime OK, si no, imprime NO. tambin podemos comparar cadenas, por ejemplo: Cdigo: @echo off IF "%~1"=="hola" echo hola usamos %~1 para que aunque el usuario ponga comillas, no salga error Cdigo: @echo off IF /I "%~1"=="hola" echo hola este cdigo, solo responde si dices hola CON minsculas. /I es para hacer ms estricta la comparacin. ahora, podemos usar IF en varias lneas: Cdigo: @echo off IF EXIST %~snx1 ( echo EXISTE! ) ELSE ( echo NO EXISTE ) con parntesis (). si vamos a usar comparaciones numricas, debemos usar los siguientes cdigos de comparacin: Cdigo: EQU NEQ LSS LEQ GTR GEQ igual no igual menor que menor que o igual mayor que mayor que o igual
por ejemplo: Cdigo: @echo off echo Cual es tu edad? SET /P m= IF %m% GEQ 18 ( echo ERES MAYOR DE EDAD ) ELSE ( echo NO ERES MAYOR DE EDAD ) que regresa: Cdigo: C:\Documents and Settings\Administrador\tempcurso>acon Cul es tu edad? 19 ERES MAYOR DE EDAD C:\Documents and Settings\Administrador\tempcurso>acon Cul es tu edad? 17 NO ERES MAYOR DE EDAD Tambin podemos saber si una variable ya fue definida: Cdigo: IF DEFINED var ( echo SI ) ELSE ( echo NO ) Mezclando las subcadenas y el IF SET STRING=C:\MyDocuments\ IF "%STRING:~-1%"=="\" SET STRING=%STRING:~0,-1% ECHO String: %STRING% String: C:\MyDocuments
FOR FOR es una herramienta muy completa, nos permite analizar segmentos de la salida de comandos, funciones y el contenido de archivos. Tambin permite hacer bucles de la siguiente manera: Cdigo: FOR /L %%var IN (inicio,incremento,fin) DO (acciones) inicio, es el valor inicial, incremento es la cantidad a sumar, y fin es la cantidad a detenerse, por ejemplo: Cdigo: FOR /L %%i IN (0,1,10) DO (echo %%i) imprimir 0 1 2 3 4 5 6 7 8 9 10 sin embargo, la forma ms sencilla de usar FOR, es para numerar archivos, y hacer algo con ellos.. por ejemplo: Cdigo: FOR %%x in (x*) DO echo %%x mostrar todos los archivos que empiezan con x. para SOLO mostrar directorios: Cdigo: FOR /D %%x in (m*) DO echo %%x el modificador "/D", mostrar solo los directorios, que empiecen con m. El comando se puede hacer "recursivo", es decir, que se ejecute dentro de cada directorio, con el comando "/R", por ejemplo, en una estructura de directorios como la siguiente: Cdigo: adios algo xx hola al ejecutar el comando: Cdigo: FOR /R /D %%x in (a*) DO echo %%x C:\adios C:\adios\algo sin embargo, al ejecutar el comando.. Cdigo: FOR /R %%x in (*x*) DO echo %%x C:\ax.txt C:\adios\sx.txt C:\adios\wwx.txt C:\adios\algo\kkx.txt C:\adios\algo\xx\xx.txt C:\hola\ax.txt C:\hola\rx.txt nos mostrara todos los archivos que coinciden con la secuencia especificada, incluso podramos hacer un buscador en batch, con el uso de FINDSTR y FOR. Tenemos otro modificador, /F que nos permite usar ciertas opciones para separar el resultado de las acciones.. comandos, cadenas, o archivos. Su sintaxis es la siguiente: Cdigo: FOR /F ["opciones"] %var IN (conjunto) DO (acciones) conjunto puede ser: conjunto de archivos -> sin comillas cadena de caracteres -> con comillas dobles (" ") comando -> con comilla simple (' ') las opciones son las siguientes:
eol -> todo lo que este despus de este carcter ser ignorado (para cada lnea) skip -> nmero de lneas a saltarse al principio del archivo/comando. delims -> esto sirve para separar las strings.. si no se coloca esta opcin, se usaran como separadores "espacio" y "tab" tokens -> esto es para especificar cules segmentos, delimitados por "delims", sern pasados a las variables.. por ejemplo: 1,2,3 solo pasara los primeros 3 segmentos. 1,2* pasara 2 segmentos, el primero y todo lo que este despus (el * regresa todo el resto de la lnea) 1,2-6,8,9* regresara 4 segmentos, el primero, desde el segundo hasta el sexto, el octavo y el resto de la lnea, despus del noveno, el signo de menos (-) genera intervalos. por ltimo, est la opcin: usebackq -> que cambia la forma de interpretar si es string o comando, de la siguiente manera: 'cadena' `comando` Nota: [`] es diferente al carcter de acento [] por ejemplo, el siguiente comando: Cdigo: FOR /F "tokens=1,3-5,7-9,10* delims= " %%i IN ("George no es malvado, es bondadoso, siempre piensa en los dems.") DO echo %%i %%j %%k %%l tonto, %%m %%n %%o matar a %%p %%q dar de resultado: Cdigo: George es malvado, es tonto, siempre piensa en matar a los dems.
Funciones El uso de argumentos, de etiquetas y de filtros nos ayuda mucho al momento de escribir un cdigo. Muchos creen que las etiquetas solo sirven para los goto.. sin embargo una etiqueta puede servir de funcin y recibir parmetros. miren, el siguiente programa: Cdigo: @echo off call:funcion 1 2 3 call:funcion %* goto:EOF :funcion echo Estoy en: %~nx0-^>%0 %* al ser llamado, por ejemplo en: Cdigo: C:\>ejemplo Estoy en: ejemplo.bat->:funcion 1 2 3 Estoy en: ejemplo.bat->:funcion el primero muestra los parmetros enviados por el batch (1 2 3), y el segundo los parmetros enviados al programa. en este otro ejemplo: Cdigo: C:\>ejemplo HOLA MUNDO Estoy en: ejemplo.bat->:funcion 1 2 3 Estoy en: ejemplo.bat->:funcion HOLA MUNDO la funcion obtiene tambin los argumentos del programa. hasta ahora.. todo es igual a usar goto a excepcin del uso de argumentos, sin embargo.. si queremos hacer un.. "return", se hace usando: goto:EOF entonces, en situaciones como: Cdigo: @echo off&call:main&goto:EOF :suma set /A res=%1 + %2 echo %res% goto:EOF :resta set /A res=%1 - %2 echo %res% goto:EOF :multiplica set /A res=%1 * %2 echo %res% goto:EOF :main set /P arg=Escribe 2 numeros separados por un espacio echo %arg% echo su suma es: call:suma %arg% echo su resta es: call:resta %arg% echo su producto es: call:multiplica %arg% goto:EOF como podemos ver goto:EOF se usa para regresar al orden de comandos. el resultado es algo as:
Cdigo: C:\>operaciones Escribe 2 numeros separados por un espacio 6 2 6 2 su suma es: 8 su resta es: 4 su producto es: 12
Includes Para hacer un "include" o incluir un archivo, solo debes llamarlo as: archivo_a_incluir.bat funcion argumentos y en el archivo a incluir, debe de estar al principio: @echo off&call:%*&goto:EOF queda algo as: Cdigo: @echo off&call:%*&goto:EOF :funcion1 ... :funcion2 ... por ejemplo: --inclu.bat-Cdigo: @echo off&call:%*&goto:EOF :cabeza echo ############### echo # Hecho por: # echo # ErDebugger # echo ############### goto:EOF :uso echo uso: echo %~nx0 Nombre goto:EOF :nombre echo Hola %* goto:EOF --inicio.bat-Cdigo: @echo off if "%~1"=="" ( inclu.bat cabeza inclu.bat uso ) else ( inclu.bat nombre %~1 ) esto dara este resultado: Cdigo: C:\>inicio ############### # Hecho por: # # ErDebugger # ############### uso: inclu.bat Nombre C:\>inicio ErDebugger Hola ErDebugger C:\>
Misc Algunos filtros y comandos interesantes: comando | more muestra el resultado del comando de forma paginada comando | sort muestra el resultado del comando de forma ordenada TITLE "algo" cambia el ttulo de la ventana de CMD SUBST ruta/a/alguna/carpeta [letra_unidad] asigna a letra_unidad la ruta de acceso FIND "cadena" busca cierta cadena en un archivo (se puede usar como filtro), con el modificador /v encuentra solo las que NO tienen la lnea especificada. (para mas info, escribe en CMD: FIND /?) FINDSTR extensin de FIND, acepta expresiones regulares, y bsqueda general (lo ms parecido que DOS tiene a grep), descripcin detallada: Cdigo: Busca cadenas en los archivos. FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/P] [/F:archivo] [/C:cadena] [/G:archivo] [/D:lista de directorios] [/A:atributos de color] [cadenas] [[unidad:][ruta]nombredearchivo[ ...]] /B /E /L /R /S Hace coincidir los modelos si estn al principio de la lnea. Hace coincidir los modelos si estn al final de la lnea. Literalmente utiliza cadenas de bsqueda. Utiliza cadenas de bsqueda como expresiones regulares. Busca archivos que coinciden en el directorio actual y en todos los subdirectorios. /I Especifica que la bsqueda no distingue maysculas de minsculas. /X Imprime lneas que coinciden con exactitud. /V Slo imprime lneas que no contienen una correspondencia. /N Imprime el nmero de la lnea antes de la lnea que coincide. /M Slo imprime el nombre de archivo si el archivo contiene una correspondencia. /O Imprime un carcter de desplazamiento antes de las lneas que coinciden. /P Omite archivos con caracteres que no son imprimibles /A:attr Especifica atributos de color con dos dgitos hexadecimales. Ver "color /?" /F:archivo Lee la lista de archivos desde el archivo especificado (/ significa consola). /C:cadena Utiliza una cadena especificada como una bsqueda de cadena literal. /G:archivo Coge la bsqueda de archivos desde el archivo especificado (/ significa consola). /D:dir Busca un signo de punto y coma de la lista delimitada de directorios cadenas Texto que se debe buscar. [unidad:][ruta]nombredearchivo Especifica un archivo o archivos que buscar. Utiliza espacios para separar mltiples cadenas de bsqueda a no ser que el argumento lleve un prefijo con /C. Por ejemplo, 'FINDSTR "qu tal" x.y' busca "qu" o "tal" en el archivo x.y. 'FINDSTR /C:"qu tal" x.y' busca "qu tal" en el archivo x.y. Expresin regular de referencia rpida: . Comodn: cualquier carcter * Repetir: cero o ms ocurrencias de un carcter previo o de clase ^ Posicin de lnea: comienzo de la lnea $ Posicin de lnea: fin de lnea [clase] Clase de carcter: cualquier carcter en la serie [^class] Clase inversa: cualquier carcter que no est en la serie [x-y] Intervalo: cualquier carcter que est dentro del intervalo
\x \<xyz xyz\>
especificado Escape: uso literal de un metacarcter x Posicin de palabra: principio de palabra Posicin de palabra: fin de palabra
Para obtener una informacin ms completa sobre expresiones regulares de FINDSTR referirse al Comando de referencia Command en lnea.
start "ttulo ventana nueva" [OPCIONES] comando argumentos START tiene ms opciones de las que son usadas comnmente. "ttulo ventana nueva" especifica el ttulo de la ventana que se generar. las opciones entre otros contienen: /Druta - el programa inicia en el directorio.. /B - la aplicacin se inicia sin ventana /I - se inicia la aplicacin con el entorno original, es decir las modificaciones al entrono hechas en esta sesin, no afectaran el nuevo programa /MIN - La nueva ventana se inicia minimizada /MAX - La nueva ventana se inicia maximizada /SEPARATE - El programa se inicia en una zona de memoria separada /SHARED - El programa se inicia en una zona de memoria compartida Iniciar en prioridades: /LOW - baja /NORMAL - normal /HIGH - alta /REALTIME - tiempo real /ABOVENORMAL - sobre lo normal /BELOWNORMAL - debajo de lo normal /WAIT - Inicia el programa, y espera hasta que termine de ejecutarse por ejemplo, si quieren abrir un programa sin generar una ventana, por ejemplo netcat, podran hacer algo as: start /B /SEPARATE /HIGH /I /D %WINDIR% nc -L -p 1337 |exit que lo inicia en una zona de memoria separada, con prioridad alta, en el contexto original, y en %windir%
EOF EOF es una etiqueta que define el fin del archivo, sirve para terminar funciones, y en este caso, solo sirve para terminar el documento , espero les sirva