Concernant les fichiers batch Windows: Existe-t-il un moyen de répertorier tous les fichiers (ou tous d'un type spécifique) d'un répertoire donné et de ses sous-répertoires, y compris les chemins relatifs au répertoire actuel (ou de recherche) de la liste?
Par exemple, si je veux tous les fichiers .txt du répertoire et des sous-répertoires actuels avec leurs chemins d'accès complets, je peux le faire.
for /r . %%g in (*.txt) do echo %%g >> C:\temp\test.txt
ou
dir *.txt /b /s >> C:\temp\test.txt
et je vais obtenir quelque chose comme
C:\test\Doc1.txt
C:\test\subdir\Doc2.txt
C:\test\subdir\Doc3.txt
Si je fais
for /r . %%g in (*.txt) do echo %%~nxg >> C:\temp\test.txt
Je vais avoir quelque chose comme
Doc1.txt
Doc2.txt
Doc3.txt
Mais ce que je veux vraiment, c'est:
Doc1.txt
subdir\Doc2.txt
subdir\Doc3.txt
C'est possible?
Si mon message est trop déroutant: je veux fondamentalement liste récursivement les fichiers dans Linux CLI avec chemin relatif au répertoire en cours, mais juste pour Windows.
Vous pouvez simplement obtenir la longueur de caractères du répertoire courant et les supprimer de votre 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
)
Le moyen le plus simple (mais pas le plus rapide) de parcourir une arborescence de répertoires et de répertorier les chemins de fichiers relatifs consiste à utiliser FORFILES .
forfiles /s /m *.txt /c "cmd /c echo @relpath"
Les chemins relatifs seront cités avec un .\
un péché
".\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 .\
:
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
Cette réponse ne fonctionnera pas correctement avec des chemins racine contenant des signes égaux (=
). (Merci @dbenham pour l'avoir signalé.)
EDITED: Correction du problème avec les chemins contenant !
, encore repéré par @dbenham (merci!).
Au lieu de calculer la longueur et d’extraire les sous-chaînes, vous pouvez utiliser une approche différente:
stocker le chemin racine;
effacez le chemin 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
)
La variable r
est affectée au répertoire actuel. À moins que le répertoire en cours soit le répertoire racine d'un lecteur de disque, il ne se terminera pas par (Ce n'est plus le cas, car le script lit maintenant le \
, que nous modifions en ajoutant le caractère.__CD__
variable, 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 produisons la variable, en supprimant le chemin racine.
Bien sûr, vous pouvez écrire un algorithme récursif dans Batch qui vous permet de contrôler exactement 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
@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
)