Comando FOR para archivos BAT

Gracias a: http://profesoremiliobarco.blogspot.com/

El comando FOR sirve para ejecutar bucles de instrucciones, y es una instrucción que se encuentra disponible en todos los lenguajes de programación. Un bucle son varias repeticiones de algunas instrucciones.


Este comando suele ser el más complicado de entender para las personas que empiezan a escribir archivos BAT complejos. Aqui intentaré explicar todas las opciones y usos del comando FOR, así como intentar resolver las dudas que los usuarios de Internet me puedan plantear.

La sintaxis normal del comando FOR es:

FOR %var IN (lista) DO ( 
    comando
    comando
     ...


Pero si lo vamos a usar dentro de un archivo BAT será así:

FOR %%var IN (lista) DO ( 
    comando
    comando
     ...
)


Observa que la variable "var" ahora va precedida por dos simbolos de "%". Además, si este for está dentro de un archivo BAT, el nombre de la variable debe ser UNA SOLA LETRA (p.ej: %%n, %%i,  %%j , etc )


EJEMPLO1


Para que la variable del FOR vaya tomando distintos valores dentro de una lista determinada:

for %A in (uno dos tres cuatro) do (
   echo %A
)

Esto sacará por pantalla las palabras que están entre parentesis, separadas linea a linea.

Y si el "for" está dentro de un archivo BAT, y tome los valores posicionales que se pasan cuando se llama al archivo desde la consola:

for %%x in (%*) do (
    echo %%x
)

EJEMPLO2

Si queremos recorrer una lista de archivos de un determinado directorio (solo archivos, no directorios):

for %f in (*) do (
   echo %f
)

y si queremos mover a la papelera de reciclaje algunos archivos con determinadas extensiones:

for %f in (*.jpg, *.mp3, *.bmp) do (
   move %f c:\recycler
)


MEJORAS EN EL FOR

RECURSIVIDAD:
FOR /R [ruta] %V IN (lista) DO comando
 

DIRECTORIOS: 
FOR /D        %V IN (lista) DO comando    
 

LISTA CON CONTADOR: 
FOR /L        %V IN (inicio, incremento, fin) DO comando 

RECORRIDO DE TOKENS EN LINEAS DE TEXTO:
FOR /F ["tokens=... delims=..."] %V IN (archivo | 'comando' | "cadena") DO comando


EJEMPLO3:  (parametro /R)

Recorrer y mostrar todos los archivos de la unidad C: empezando en su directorio raiz, y recorriendo recursivamente el resto de directorios que contiene:

for /R c:\ %v in (*) do (
   echo %v
)

Una variacion de este ejemplo sería el buscar un determinado tipo de archivos dentro de un directorio recursivamente. Voy a buscar todos los archivos "dll" y "exe" dentro del directorio "windows":

for /R c:\windows %v in (*.dll, *.exe) do (
   echo %v
)


EJEMPLO4: (parametro /D)

Si lo que me interesa es listar los directorios en vez de los archivos:

for /D %v in (*) do (
   echo %v
)

Y si lo quiero hacer recursivamente puedo añadir "/R" al comando anterior:

for /R /D %v in (*) do (
   echo %v
)
 
Y si quiero hacerlo recursivamente desde un directorio concreto (p.ej: c:\windows):

for /R c:\windows /D %v in (*) do (
   echo %v
)



EJEMPLO5: (parametro /L)

Para crear un tipico bucle contador de 1 a 10, saltando de 1 en 1:

for /L %x in (1, 1, 10) do (
   echo %x
)

Y saltando de 2 en 2

for /L %x in (1, 2, 10) do (
   echo %x
)

Y de 3 en 3:

for /L %x in (1, 3, 10) do (
   echo %x
)

etc.

Hay que observar que el primer numero dentro del parentesis es el valor inicial que tomará la variable "%x", el segundo numero es el incremento que sufrirá dicha variable en la proxima iteracion del FOR, y el tercer número es el valor máximo que tomará dicha variable y que cuando alcance o supere dicho valor, el bucle FOR terminará de ejecutarse.

EJEMPLO6:

Archivo BAT que crea varios archivos vacios y los llama a todos con el mismo nombre, pero terminados en un numero diferente:

@echo off
cls

set/p nombre=Indica el nombre de los archivos a crear:

set/p num=Cuantos archivos hay que crear?:

for /L %%x in (1, 1, %num%) do (
  echo 2> %%x%nombre
)


 EJEMPLO7: (parametro /F)

Recorrer un archivo y mostrar solo la primera palabra de cada linea:

for /F %%x in (fichero.txt) do (
  echo %%x
)

 El FOR va recorriendo todas las lineas, y cada linea se ha dividido en "tokens" (token=palabra). La variable del for almacena la primera palabra de cada linea.

EJEMPLO8: (parametro /F con tokens)

Podemos seleccionar varios tokens mediante la clausula tokens=. Los distintos tokens se irán guardando automáticamente en variables alfabeticamente consecutivas a partir de la variable creada en el for.

En el siguiente ejemplo nos quedamos con los tokens (palabras) 1, 3 y 5 de cada linea:

for /F "tokens=1,3,5" %%a in (fichero.txt) do (
  echo %%a %%b %%c
)

 observa que aunque yo solamente he definido la variable "%%a" en el FOR, las variables "b" y "c" se crean automaticamente.

Podemos escoger rangos, como en el siguiente ejemplo, en el que vamos a escoger los tokens del 1 al 3, y además el token 5

for /F "tokens=1-3,5" %%a in (fichero.txt) do (
  echo %%a %%b %%c %%d
)


O si queremos coger la linea completa a partir de la septima palabra:

for /F "tokens=7*" %%a in (fichero.txt) do (
  echo %%a
)

Y si queremos coger la linea completa:

for /F "tokens=*" %%a in (fichero.txt) do (
  echo %%a
)



 EJEMPLO8: (parametro /F con delimitadores)

Además de la clausula "tokens" con el parámetro "/F", podemos usar la clausula "delims", que indica la separacion entre los distintos tokens. Por defecto, los caracteres delimitadores entre tokens son los espacios en blanco y los tabuladores.

En el siguiente ejemplo anulamos los delimitadores y obtenemos lo mismo que antes:

for /F "delims=" %%a in (fichero.txt) do (
  echo %%a
)

Si queremos usar como delimitadores los simbolos de puntuacion, como el punto, la coma, el punto y coma, etc...:

for /F "delims=.,;:" %%a in (fichero.txt) do (
  echo %%a
)

esto solo imprimirá por pantalla la linea completa hasta que encuentre alguno de los delimitadores que le hemos indicado.

También se pueden combinar delimitadores y tokens:

for /F "tokens=7* delims=,." %%a in (fichero.txt) do (
  echo %%a
)

 También se pueden usar otras cláusulas como:

  • skip=n, que se saltaría las n primeras líneas del archivo, empezando a procesar la n+1
  • eol=carácter, que interpreta las líneas que comienzan por ese carácter como líneas de comentarios y se las salta.
  • useback, que cambia la semantica de la lista: (`comando`), ('cadena'), (archivo) ("archivo1" "archivo2" "archivo3")

EJEMPLO9: (uso de comandos dentro de la Lista)

Se puede sustituir la lista de valores que tiene que tomar la variable, por la ejecución de un comando, como en el siguiente ejemplo:

for /F "tokens=15 delims=:" %%a in (ipconfig ^| find IP) do (
  echo %%a
)

 Observar el caracter de escape "^" necesario para que la tubería se interprete dentro del comando en vez de ser interpretado para el for

EJEMPLO10: (parámetro /F con cadenas)

Podemos extraer distintas partes del valor de una variable. Por ejemplo, si mostramos el valor de la variable "date", nos dará una fecha con el siguiente formato:

07/05/2012

donde el dia, la fecha y la hora están separados por un carácter que sirve de delimitador: "/"

Para extraer las distintas partes de la fecha utilizamos el siguiente ejemplo (dentro de un archivo BAT):

for /F "tokens=1-3 delims=/:" %%a in (%date%) do (
  echo Hoy es %%a del mes %%b del año %%c
)

lo cual nos proporciona la siguiente salida por pantalla:

Hoy es 07 del mes 05 del año 2012


EJEMPLO 11: Variables dentro de un FOR

Hay veces que necesitamos usar y actualizar otras variables en el FOR, a parte de la que se crea en la cabecera del mismo, o incluso anidar un FOR dentro de otro FOR.

Para poder acceder a dichas variables hay que poner al principio del archivo BAT la siguiente linea (es MUY MUY IMPORTANTE ponerlo, porque sino no funcionará bien nuestro programa BAT):

setlocal enabledelayedexpansion

y además para acceder al valor de dichas variables hay que usar el simbolo de admiración "!", en lugar del simbolo "%"

Por ejemplo, el siguiente archivo BAT nos muestra la tabla de multiplicar de un numero que yo le indique por teclado:

tabla.bat

@echo off
cls
setlocal enabledelayedexpansion

rem En la variable num guardo que tabla de multiplicar quiero ver
set /p num=Quieres ver la tabla de multiplicar del numero...
cls

echo TABLA DEL %num%
echo ===============
echo .

for /L %%a in (1,1,10) do (
  set /a result=%num%*%%a
  echo %num% * %%a = !result!
  rem Hay que observar que para acceder al valor de la variable 
  rem "result" hay que cambiar los caracteres de porcentaje "%"
  rem por caracteres de admiracion "!"
)

Si quiero ver todas las tablas de multiplicar, debo anidar un FOR dentro de otro, y el archivo BAT quedaría así:

todastablas.bat

@echo off
cls
setlocal enabledelayedexpansion

for /L %%i in (1,1,10) do (

echo TABLA DEL %%i
echo ===============
echo .

    for /L %%a in (1,1,10) do (
      set /a result=%%i*%%a
      echo %%i * %%a = !result!

    )
    pause
    cls
)

Si no queremos usar el comando "setlocal enabledelayedexpansion" podemos ejecutar nuestro archivo BAT desde un terminal con "sustitución retardada". Para ello ejecutamos lo siguiente:

cmd /v:on

PETICIONES DE ARCHIVOS BAT DE LOS USUARIOS

Aquí iré añadiendo, cuando tenga tiempo, las soluciones a lo que me vais planteando los que comentais en esta entrada.

  • El usuario Nano me preguntó: 
"Me gustaría crear un archivo bat, el cual me mostrara la fecha de creación de un archivo.
el resultado debería ser:

La fecha del archivo es: 20/05/2013"

SOLUCIÓN:

@echo off
cls

echo Este programa BAT te pide el nombre de un archivo y te muestra la fecha en la que fue creado

dir

echo.

rem en la variable "archivo" meto el nombre del archivo
set /p archivo="Introduce el nombre del archivo:"

cls

rem ahora con el siguiente "for" extraigo (con el comando "find") la unica linea donde estan los caracteres "/" del listado que me saca el comando dir, porque ahi esta la fecha que quiero obtener

rem es muy importante poner las comillas simples en su lugar correspondiente

rem y tambien es muy importante poner el acento circunflejo "^" justo antes del caracter filtro "|", porque sino no funcionara

for /F "tokens=1" %%x in ('dir %archivo% ^| find "/"') do (
 echo El archivo %archivo% fue creado el %%x
)


  • La usuaria Alejandra me preguntó:

"Quiero recorrer a partir de un directorio todos los archivos y renombrar los que tienen una extension, por ejemplo jpg
tendria que renombrar todos incusive si hay subdirectorios."

Esto NO SE PUEDE HACER, porque a cada archivo le tendrías que poner un nombre diferente (no puede haber 2 o más archivos que tengan el mismo nombre y la misma extensión), tendrías que ir cambiandoselo uno por uno.


Sin embargo, si puedo cambiar la extensión de todos los archivos de un determinado directorio, que tengan una extensión en concreto (por ejemplo ".avi", ".mp3", o cualquier otra), este sería el archivo BAT:

SOLUCION


@echo off
setlocal enabledelayedexpansion
cls
echo Este archivo BAT recorre un directorio y sus subdirectorios y renombra los archivos que tengan una determinada extension:
echo.
echo.
set /p dir="Introduce la ruta del directorio:"
set /p ext="Introduce la extension de los archivos que se van a cambiar:"
set /p nueva="Introduce la nueva extensión que van a tener esos archivos:"
echo.
echo.

rem Me situo en el directorio en cuestion
cd %dir%

rem Cambio la extension de los archivos del directorio actual
ren *.!ext! *.!nueva!

rem Con el siguiente "for" me voy metiendo en los subdirectorios del directorio actual y les voy cambiando la extension a los archivos elegidos

for /D /R %%x in (*) do (
  cd %%x
  ren *.!ext! *.!nueva!
  cd ..
)



  • El usuario Anonimo me preguntó:

"Quiero hacer un archivo BAT que: Programe la ejecución de una copia de seguridad del contenido de una carpeta a otra a la hora que se pase como parámetro."

SOLUCION:

Aqui hay que preguntar 3 cosas al usuario: la carpeta que quiere copiar, la carpeta destino, y la hora a la que se efectuará esa copia. Y después usar el comando "at" para programar la tarea a una hora determinada, y el comando "xcopy" para copiar un directorio con todo su contenido.


@echo off

cls
set /p origen="Escribe la ruta de la carpeta que quieres copiar:"

set /p destino="Escribe la ruta de destino"
set /p hora="Escribe la hora a la que se hara esta copia: hh:mm"

at %hora% xcopy %origen% %destino% 

Pero si la hora se la pasamos desde la linea de comandos sería así:

@echo off

cls
set /p origen="Escribe la ruta de la carpeta que quieres copiar:"

set /p destino="Escribe la ruta de destino"


at %1 xcopy %origen% %destino%

  • El usuario Anonimo también me preguntó:

"Quiero hacer un archivo BAT que: Muestre el nombre y tamaño de los archivos de la carpeta
activa cuyo tamaño sea superior a la cantidad que se indique como parámetro"

SOLUCION:

Con un for hay que ir recorriendo todos los archivos del directorio actual, y comparar su tamaño con el número de bytes que se le ha pasado como parametro posicional número 1 (%1).


@echo off
set enabledelayedexpansion
cls

echo Los archivos mas grandes de %1 bytes son:
echo.

REM Recorro todos los archivos del directorio actual y comparo si
REM su tamaño es mayor que el tamaño del archivo pasado por la
REM linea de comandos

for %%a in (*) do (
  for /F "tokens=3" %%t in ('dir /N /-C %%a ^| find "/"') do (
    if %%t gtr %1 echo %%a = %%t bytes
  )
)

REM He usado el caracter "/" para filtrar las lineas generadas
REM por el comando dir, puesto que las lineas que contienen ese
REM caracter, son las que tienen una fecha, y por tanto tienen
REM los datos de un archivo concreto.
REM Además uso las opciones /N y /-C del comando dir para que
REM se muestren todos los datos de los archivos, entre ellos
REM el tamaño, y la opcion /-C evita que aparezca el separador
REM de miles en el tamaño del archivo, que luego al hacer la
REM comparación me dará problemas si aparece.



  • El usuario Victor Castillejo me preguntó:

"Quiero hacer un archivo BAT que: me muestre la linea numero 4 de un archivo en concreto"

He hecho un archivo bat mejor que te pida el nombre de un archivo, y una linea inicial y una final y te imprima todas las lineas que están entre ambos numeros

SOLUCION:

@echo off
cls
setlocal enabledelayedexpansion

set/p nombre=Indica el nombre del archivo:
set/p numero=Indica el numero de linea inicial que quieres mostrar:
set/p final=Indica el numero de linea final que quieres mostrar:

set num=1

for /f "tokens=*" %%a in (%nombre%) do (
  if !num! geq %numero% (
    if !num! leq %final% echo %%a
  )
  set /a num = !num! + 1
)



  • El usuario Anonimo me preguntó:

"Quiero hacer un archivo BAT que me muestre las 30 ultimas lineas de un archivo en concreto"

He hecho un archivo bat mejor que te pida el nombre de un archivo, y las lineas finales, y te imprima las lineas finales que el usuario indique

SOLUCION:


@echo off
cls
setlocal enabledelayedexpansion

set/p nombre=Indica el nombre del archivo:
set/p lineas=Indica cuantas lineas quieres mostrar del final del

archivo:

set num=1

REM Con el siguiente for contare cuantas lineas tiene el archivo
for /f "tokens=*" %%a in (%nombre%) do (
  set /a num = !num! + 1
)

echo El archivo %nombre% tiene %num% lineas. Las ultimas %lineas% lineas son las siguientes:

echo.
echo.

REM En la variable inicio estara el numero de la linea desde la que tenemos que imprimir por pantalla
set /a inicio = !num! - !lineas!
set num=1

for /f "tokens=*" %%a in (%nombre%) do (
  if !num! geq %inicio% (
    echo %%a
  )
  set /a num = !num! + 1



  • El usuario Fran me preguntó:

"Quiero hacer un archivo BAT que lea un fichero que tiene un indice (un numero al principio de cada linea) y que las lineas que estan entre 0 y 249 las guarde dentro de un archivo (archivo1.txt) y las restantes lineas las guarde en otro archivo (archivo2.txt)"

SOLUCION:



@echo off
cls
setlocal enabledelayedexpansion

REM Los archivos resultantes van a ser "archivo1" y "archivo2"
REM Al principio, estos archivos deben estar vacios
echo. > archivo1.txt
echo. > archivo2.txt


set/p nombre=Indica el nombre del archivo:

REM ahora tomare las lineas del archivo de una en una
REM leyendo su primer token, que sera el indice, y el
REM resto de la linea, que sera lo que meta en el fichero
REM resultante
for /f "tokens=1,*" %%a in (%nombre%) do (
  if %%a lss 250 (
    echo %%a %%b >> archivo1.txt
  ) else (
    echo %%a %%b >> archivo2.txt
  )



  • El usuario Angel (anonimo) me preguntó:

"Quiero hacer un archivo BAT que recorra el árbol que cuelga de un directorio, y me copie un archivo determinado en cada uno de los directorios de dicho árbol"

SOLUCION:


@echo off

REM Guardo en la variable ruta la ruta del directorio actual
set ruta=%cd%

set /p nombre=Escribe el archivo del directorio actual que quieres copiar:

REM Ahora en la variable ruta, genero la ruta absoluta del
REM archivo que quiero copiar
set ruta=%ruta%\%nombre%

REM Con el siguiente FOR recorro recursivamente todos los
REM directorios del directorio actual y copio el archivo
REM que he seleccionado dentro de ellos
for /R /D %%v in (*) do (
   copy "%ruta%" "%%v\%nombre%"
)


  • El usuario Jorge Rainof me preguntó:

"Quiero hacer un archivo BAT que sume los datos numericos que se encuentran en las lineas de un fichero de texto. Estos numeros tienen separador de miles"

SOLUCIÓN:

@echo off
cls
setlocal enabledelayedexpansion


set suma=0

set /p archivo=Que archivo contiene los numeros para sumar?:

for /f "tokens=1-5 delims=." %%a in (!archivo!) do (
   set num=%%a%%b%%c%%d%%e
   set /a suma=!suma! + !num!
   echo + !num!
)

echo ------------------------
echo !suma!

pause 



OTRA SOLUCIÓN (propuesta por Jorge Rainoff):

@echo off
cls
setlocal enabledelayedexpansion

set suma=0


set /p archivo=Que archivo contiene los numeros para sumar?:






REM en el siguiente "for", a diferencia del anterior, solo
REM voy a coger el primer "token", asi que no hace falta
REM que lo indique explicitamente en el "for".
REM En la variable "%%a" estará el número que quiero sumar,
REM y para quitarle los puntos intermedios, asigno su valor
REM a otra variable llamada "num", y a ésta le quito los
REM puntos con la siguiente instrucción: "set num=!num:.=!"
 

for /f %%a in (!archivo!) do (
  set num=%%a
  set num=!num:.=!
  echo + !num!
  set /a suma= !suma! + !num!
)

echo ------------------------
echo !suma!

pause



  • El usuario Anonimo me preguntó:

"Quiero hacer un archivo BAT que copie el ultimo archivo modificado a un directorio"

SOLUCIÓN:

@echo off
cls
setlocal enabledelayedexpansion

REM Este programa BAT copiara en el directorio "copia"
REM el ultimo fichero modificado en el directorio actual

set num=1

for /f "tokens=*" %%a in ('dir /o:-d /a:-d /b') do (
  if !num! equ 1 (
    echo El archivo modificado mas reciente es: %%a
    copy "%%a" copia
    dir copia\%%a
  )
  set num=2 
)



  • El usuario Fernando me preguntó:

"Quiero hacer un archivo BAT que extraiga un caracter de una variable usando un FOR"

Esto no lo puedes hacer con un for.

En los lenguajes de programación como Pascal, Java, C, etc. , existen funciones específicas que sirven para extraer una subcadena que se encuentre dentro de una cadena de caracteres, pero en la programación de archivos BAT no hay ningún comando que haga esto directamente (o por lo menos yo no lo conozco).

Se puede hacer una especie de bucle (usando etiquetas e instrucciones goto) que vayan pasando por el primer caracter de una variable ( usando " echo %variable:~0,1% " ) y lo vayamos desplazando un lugar hacia la izquierda ( usando " set variable=%variable:~1% " ). Así haremos que se vayan imprimiendo por pantalla todos los caracteres de la variable, linea por linea.

SOLUCIÓN:



@echo off
setlocal enabledelayedexpansion
cls

set /p frase="Escriba una frase: "

:bucle

  if "%frase%" equ "" goto fin

  set letra=%frase:~0,1%
  set frase=%frase:~1%
 

goto bucle

:fin
pause



  • El usuario Mauricio Espinosa Bustos me preguntó:

"Quiero hacer un archivo BAT que elija el archivo de mayor tamaño de un mes y un año concretos, cuyo nombre empiece por TARRO.D[fecha]"

Supongo que la fecha tiene este formato: dd-mm-aaaa

SOLUCIÓN:

@echo off
cls
setlocal enabledelayedexpansion

REM Este programa BAT mostrará cual es el archivo mayor
REM del directorio actual, que empieza por TARRO.D[fecha]

set /p mes="Indica el mes con dos digitos : "
set /p anio="Indica el anio con 4 digitos : "

set num=1

for /f "tokens=*" %%a in ('dir /o:-s /a:-d /b "TARRO.D*-%mes%-%anio%"') do (
  if !num! equ 1 (
    echo El archivo de mayor tamanio del mes %mes% es: %%a
  )
  set num=2 
)


  • Mi amigo y compañero Carlos Trujillo me comentó el otro día :

"Quiero hacer un archivo BAT que me cree automaticamente carpetas para cada dia del mes de un determinado año, para guardar las fotos que voy haciendo en ellas, clasificadas por días"

SOLUCIÓN:

@echo off
cls
setlocal enabledelayedexpansion


set /p mes="Escribe el mes : "
set /p anio="Escribe el anio : " 


REM Voy a preguntar cuantos dias tiene el mes
REM para saber cuantas carpetas tengo que hacer

set /p dias="Cuantos dias tiene este mes? :" 



for /L %%d in ( 1 , 1 , %dias% ) do (
  mkdir "fotos %%d-%mes%-%anio%"  




  • El usuraio Alcides Dominguez García preguntó :

"Tengo el archivo "datos.txt" que es como el siguiente:

86134 31965 01706 10304 20243 30011 40096 53006 61254 70500 333 10377 55103=
86170 32970 01604 10286 20203 39988 40089 53003=
86185 NIL=
86192 32970 00000 10282 20183 39895 40109 63204 52004=
86210 32570 11802 10302 20225 39769 40103 52020 81200 333 10374 55110
81833=
86218 31960 01504 10284 20219 30021 40116 53005 70400
55103=


en el que cada linea termina en el caracter "=". Quiero obtener aquellos valores de cada linea que empiecen por un numero concreto"

 SOLUCIÓN:

 @echo off
cls
setlocal enabledelayedexpansion

REM Voy a pedir al usuario que me diga que numeros quiere
REM ver por pantalla, dependiendo de su primer digito
 

set /p num=Por que digito empiezan los numeros que estas buscando? (0-9) :

REM voy a ir extrayendo linea por linea del archivo
REM "datos.txt" teniendo en cuenta que el caracter "="
REM marca el final de una linea

for /f "tokens=1 delims==" %%a in (datos.txt) do (
  set linea=%%a

  REM ahora voy recorriendo cada dato de la linea extraida

  for %%b in (!linea!) do (
    set dato=%%b

    REM comparo el primer digito de la variable "dato" con
    REM el criterio de busqueda que le indique al principio
    REM y si coinciden lo muestro por pantalla

    if "!dato:~0,1!" == "!num!" echo !dato!
  )
)



  • El usuraio Anonimo preguntó :

"Tengo el archivo "datos2.txt" que es como el siguiente:

000001 texto
000003 texto
000004 texto
000007 texto
..

en el que cada linea empieza por un numero de 6 digitos rellenado con ceros a la izquierda. Los numeros de esas lineas no son correlativos. ¿Como podría corregirlos automaticamente para que si lo fueran?"

SOLUCIÓN:

@echo off
cls
setlocal enabledelayedexpansion

set relleno=000000
set num=1

echo. > temporal.txt

REM recorro linea por linea el archivo "datos2.txt", le
REM quito el numero de 6 cifras que tiene al principio
REM para despues ponerle otro numero de 6 cifras
REM correctamente numerado, empezando por el 000001

for /f "tokens=1,*" %%a in (datos2.txt) do (
  set num2=!relleno!!num!
  set num2=!num2:~-6!
  echo !num2! %%b >> temporal.txt
  set /a num=!num!+1
)

REM Ahora sustituyo el archivo temporal.txt por datos2.txt

type temporal.txt > datos2.txt
del temporal.txt

pause





  • El usuraio Anonimo preguntó :

"Tengo varios archivos de texto, que contienen información. Quiero extraer automaticamente de cada uno de ellos las lineas que están entre las cadenas de caracteres "DISPENSER ERROR" y "RCLen".

He creado un archivo bat para extraer esas lineas de un archivo llamado "datos2.txt", aqui está la solución:

SOLUCIÓN:


@echo off
cls
setlocal enabledelayedexpansion

REM con el comando "find /n" voy a buscar la linea en la que
REM aparece la cadena de caracteres "DISPENSER ERROR", junto
REM con su numero de linea. Lo guardo en una variable
REM llamada inicio
for /f %%a in ('find /n "DISPENSER ERROR" datos2.txt ^| more

+2') do (
  set inicio=%%a
)

REM ahora busco el numero de linea en la que aparece "RCLen"
REM y lo guardo en la variable "fin"
for /f %%a in ('find /n "RCLen" datos2.txt ^| more +2') do (
  set fin=%%a
)

REM ahora necesito extraer el numero que se encuentra entre
REM los Corchetes [45], de la variable inicio, porque en
REM esa linea se encuentran "DISPENSER ERROR". Para ello
REM voy a hacer el siguiente bucle

set inicio=!inicio:~1!
set ini=

:bucle1

if "!inicio:~0,1!" == "]" goto :continuar

set ini=!ini!!inicio:~0,1!
set inicio=!inicio:~1!
goto bucle1

:continuar

REM ahora extraigo el numero de linea en el que se encuentra
REM la cadena RCLen, con el siguiente bucle

set fin=!fin:~1!
set final=

:bucle2

if "!fin:~0,1!" == "]" goto :continuar2

set final=!final!!fin:~0,1!
set fin=!fin:~1!
goto bucle2

:continuar2

REM ahora en las variables "ini" y "final" tengo los numeros
REM de las lineas que debo mostrar del archivo datos2.txt

set num=1

for /f "tokens=*" %%a in (datos2.txt) do (
  if !num! geq !ini! (
    if !num! leq !final! (
      echo %%a
    )
  )
  set /a num=!num!+1
)

Comentarios

  1. Hola!!!
    La ejecución de comando 'wmic /output:stdout logicaldisk where drivetype=3 get freespace /format:list' da algo como

    FreeSpace=751639941120

    Quiero desde un batch mostrar un mensaje de alerta si el número es menor a 9999999999
    Además, si es posible transformar el valor 751639941120 en 751.639.941.120 (de acuerdo al valor recibido disponer los separadores de miles).
    Gracias
    Fernando

    ResponderEliminar
  2. Hola, tengo el siguiente error, no me toma el substring.

    cd C:\Oracle\Middleware
    dir /s/b RptSvr_Usuario-PC_asinst_1* > archivo_rptsvr.txt
    for /f "tokens=*" %%a in (archivo_rptsvr.txt) do (
    echo set path_completa=%%a
    echo set path_a_modificar=%path_completa:~-26,-16%
    ren %path_completa% %path_a_modificar%
    )

    ResponderEliminar
  3. Excelente explicación, muy didáctica, la mejor que he encontrado en la red sobre el uso del for en batch files. Te felicito cinco años más tarde de tu publicación.

    ResponderEliminar
  4. Estupendo tutorial sobre el FOR. A pesar de que algunos ejemplos no dan el resultado comentado, no empobrece en absoluto el resultado.
    Muchas gracias.

    ResponderEliminar
  5. Hola. Buen Trabajo el de que este FORO, los felicito.

    Quisiera saber si alguien me puede ayudar, estoy tratando de generar un codigo el cual me imprima la informacion de todos los discos duros o unidades de almacenamiento del sistema ya sean fisicas o virtuales, y que dicha informacion me la imprima en un documento por columnas, es decir nmombre de equipo, unidad, espacio total, espacio libre, espacio usado, porcentaje libre, porcentaje usado, que toda esta informacion pueda guardarse en formato .csv

    hasta ahora solo he encontrado una forma de obtener la informacion en consola, pero no puedo ejecutarlo en bat o en lotes, debe ser manual en la consola de cada equipo, pero el archivo que imprime no va separado por columnas.

    este es mi codigo
    for /f "tokens=1-3" %a in ('WMIC LOGICALDISK GET FreeSpace^,Name^,Size ^|FINDSTR /I /V "Name"') do @echo wsh.echo "%b" ^& " free=" ^& FormatNumber^(cdbl^(%a^)/1024/1024/1024, 2^)^& " GiB"^& " size=" ^& FormatNumber^(cdbl^(%c^)/1024/1024/1024, 2^)^& " GiB" > %temp%\tmp.vbs & @if not "%c"=="" @echo(& @cscript //nologo %temp%\tmp.vbs



    SI ALGUIEN PUDIERA AYUDARME A DARLE UNA REVISADA, SE LO AGARDECERE INFINITAMENTE.

    GRACIAS


    ResponderEliminar
  6. como obtener el la fecha de creación del ultimo archivo creado en una carpeta ?

    ResponderEliminar

Publicar un comentario

Dime si la información de este blog te sirvio.

Entradas populares de este blog

Guía de herramientas básicas para estudiantes: 31 apps y webs imprescindibles para ayudarte con los estudios

How to Setup and Configure Your Own GitLab Server on Ubuntu 20.04