programacion programa por para lotes lenguaje ejemplos ejecutar crear comandos batch bat avanzados avanzada archivos archivo windows batch-file cmd

windows - programa - lenguaje batch



Batch Files: enumera todos los archivos en un directorio con rutas relativas (5)

La manera más simple (pero no la más rápida) de iterar un árbol de directorios y enumerar rutas de archivos relativas es usar FORFILES .

forfiles /s /m *.txt /c "cmd /c echo @relpath"

Las rutas relativas se citarán con un encabezado ./ Como en

"./Doc1.txt" "./subdir/Doc2.txt" "./subdir/Doc3.txt"


Para eliminar las cotizaciones:

for /f %%A in (''forfiles /s /m *.txt /c "cmd /c echo @relpath"'') do echo %%~A


Para eliminar las comillas y el encabezado ./ :

setlocal disableDelayedExpansion for /f "delims=" %%A in (''forfiles /s /m *.txt /c "cmd /c echo @relpath"'') do ( set "file=%%~A" setlocal enableDelayedExpansion echo !file:~2! endlocal )

o sin usar expansión retardada

for /f "tokens=1* delims=/" %%A in ( ''forfiles /s /m *.txt /c "cmd /c echo @relpath"'' ) do for %%F in (^"%%B) do echo %%~F

Acerca de los archivos Windows Batch: ¿hay alguna manera de enumerar todos los archivos (o todos los de un tipo específico) en un determinado directorio y sus subdirectorios, incluidas las rutas relativas al directorio actual (o de búsqueda) en la lista?

Por ejemplo, si quiero todos los archivos txt en el directorio actual y los subdirectorios con sus rutas completas, puedo hacer

for /r . %%g in (*.txt) do echo %%g >> C:/temp/test.txt

o

dir *.txt /b /s >> C:/temp/test.txt

y obtendré algo así como

C:/test/Doc1.txt C:/test/subdir/Doc2.txt C:/test/subdir/Doc3.txt

Si lo hago

for /r . %%g in (*.txt) do echo %%~nxg >> C:/temp/test.txt

Voy a obtener algo como

Doc1.txt Doc2.txt Doc3.txt

Pero lo que realmente quiero es:

Doc1.txt subdir/Doc2.txt subdir/Doc3.txt

¿Es posible?

Si mi publicación es demasiado confusa: básicamente quiero " Listar archivos recursivamente en la CLI de Linux con una ruta relativa al directorio actual ", solo para Windows.


Por supuesto, puede escribir un algoritmo recursivo en Batch que le dé un control exacto de lo que hace en cada subdirectorio anidado:

@echo off set mypath= call :treeProcess goto :eof :treeProcess setlocal for %%f in (*.txt) do echo %mypath%%%f for /D %%d in (*) do ( set mypath=%mypath%%%d/ cd %%d call :treeProcess cd .. ) endlocal exit /b


Simplemente puede obtener la longitud de caracteres del directorio actual y eliminarlos de su lista absoluta

setlocal EnableDelayedExpansion for /L %%n in (1 1 500) do if "!__cd__:~%%n,1!" neq "" set /a "len=%%n+1" setlocal DisableDelayedExpansion for /r . %%g in (*.log) do ( set "absPath=%%g" setlocal EnableDelayedExpansion set "relPath=!absPath:~%len%!" echo(!relPath! endlocal )


Esta respuesta no funcionará correctamente con rutas raíz que contengan signos iguales ( = ). (Gracias @dbenham por señalar eso).

EDITADO: se corrigió el problema con las rutas que contenían ! , nuevamente visto por @dbenham (¡gracias!).

Alternativamente al cálculo de la longitud y la extracción de subcadenas, podría utilizar un enfoque diferente:

  • almacenar la ruta raíz;

  • borre la ruta raíz de las rutas de archivos.

Aquí está mi intento (que funcionó para mí):

@ECHO OFF SETLOCAL DisableDelayedExpansion SET "r=%__CD__%" FOR /R . %%F IN (*) DO ( SET "p=%%F" SETLOCAL EnableDelayedExpansion ECHO(!p:%r%=! ENDLOCAL )

La variable r se asigna con el directorio actual. A menos que el directorio actual sea el directorio raíz de una unidad de disco, no terminará con / , que modificaremos al agregar el carácter. (Ya no es el caso, ya que el script ahora lee la variable __CD__ , cuyo valor siempre termina con / (gracias @jeb!), En lugar de CD .)

En el ciclo, almacenamos la ruta del archivo actual en una variable. Luego damos salida a la variable, eliminando el camino raíz a lo largo del camino.


@echo on>out.txt @echo off setlocal enabledelayedexpansion set "parentfolder=%CD%" for /r . %%g in (*.*) do ( set "var=%%g" set var=!var:%parentfolder%=! echo !var! >> out.txt )