64 votes

Fichiers par lots : Lister tous les fichiers d'un répertoire avec des chemins relatifs

Concernant les fichiers Batch de Windows : Existe-t-il un moyen de répertorier tous les fichiers (ou tous les fichiers d'un type spécifique) dans un certain répertoire et ses sous-répertoires, y compris les chemins relatifs au répertoire actuel (ou de recherche) dans la liste ?

Par exemple, si je veux tous les fichiers txt dans le répertoire courant et les sous-répertoires avec leurs chemins complets, je peux faire ceci

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

ou

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

et j'obtiendrai quelque chose comme

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

Si je le fais

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

Je vais obtenir quelque chose comme

Doc1.txt
Doc2.txt
Doc3.txt

Mais ce que je veux vraiment, c'est :

Doc1.txt
sous-répertoire \Doc2.txt
sous-répertoire \Doc3.txt

Est-ce possible ?

Si mon message est trop confus : Je veux essentiellement " Lister les fichiers de manière récursive dans Linux CLI avec un chemin relatif au répertoire courant ", uniquement pour Windows.

43voto

dbenham Points 46458

La manière la plus simple (mais pas la plus rapide) d'itérer une arborescence de répertoires et de lister les chemins de fichiers relatifs est d'utiliser FORFILES.

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

Les chemins relatifs seront cités avec un préfixe .\ dans le cas de

".\Doc1.txt"
".\subdir\Doc2.txt"
".\subdir\Doc3.txt"

Pour supprimer les guillemets :

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

Pour supprimer les guillemets et le début .\ :

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
)

ou sans utiliser l'expansion retardée

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

25voto

jeb Points 26035

Vous pourriez simplement obtenir la longueur des caractères du répertoire actuel, et les supprimer de vos liste absolue

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
)

10voto

Andriy M Points 40395

Cette réponse ne fonctionnera pas correctement avec les chemins racine contenant des signes égaux ( = ). (Merci @dbenham de l'avoir signalé).


ÉDITION : Correction du problème avec les chemins contenant ! , encore une fois repéré par @dbenham (merci !).

Au lieu de calculer la longueur et d'extraire les sous-chaînes, vous pouvez utiliser une autre approche :

  • stocker le chemin de la racine ;

  • effacer le chemin de la racine des chemins de fichiers.

Voici ma tentative (qui a fonctionné pour moi) :

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

Le site r est assignée avec le répertoire courant. A moins que le répertoire courant ne soit le répertoire racine d'une unité de disque, il ne se terminera pas par \ que nous modifions en ajoutant le caractère. (Ce n'est plus le cas, car le script lit maintenant le fichier __CD__ dont la valeur se termine toujours par \ (merci @jeb !), au lieu de CD .)

Dans la boucle, nous stockons le chemin du fichier actuel dans une variable. Ensuite, nous sortons la variable, en supprimant le chemin de racine au passage.

8voto

Aacini Points 19316

Bien sûr, vous pouvez écrire un algorithme récursif dans Batch qui vous donne un contrôle exact de ce que vous faites dans chaque sous-répertoire imbriqué :

@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

3voto

Kedar Points 11
@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
)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X