J'ai besoin de trouver le nom du répertoire parent d'un fichier sous DOS
par ex.
Supposons que ce soit le répertoire
C:\test\pack\a.txt
J'ai un script qui me demande le nom du fichier
C:\\>getname.bat
enter file name: c:\test\pack\a.txt
maintenant, le script doit renvoyer uniquement le nom parent du fichier.
pack
et PAS le chemin d'accès parent entier au fichier.
c:\test\pack
voir ceci question
@echo OFF set mydir = "% ~ p1" SET mydir =% mydir:\=;% pour/F "jetons = * delims = ; " %% i IN (% mydir%) DOIT appeler: LAST_FOLDER %% i goto: EOF : LAST_FOLDER si "% 1" == "" ( @echo% LAST% goto: EOF ) régler LAST =% 1 SHIFT goto: LAST_FOLDER
La première réponse ci-dessus ne fonctionne pas si le nom du répertoire parent contient un espace. Les oeuvres suivantes:
@echo off
setlocal
set ParentDir=%~p1
set ParentDir=%ParentDir: =:%
set ParentDir=%ParentDir:\= %
call :getparentdir %ParentDir%
set ParentDir=%ParentDir::= %
echo ParentDir is %ParentDir%
goto :EOF
:getparentdir
if "%~1" EQU "" goto :EOF
Set ParentDir=%~1
shift
goto :getparentdir
L'appel de ce qui précède avec le paramètre "C:\Temp\Parent Dir With Space\myfile.txt" donne ce qui suit:
>GetParentDir "C:\Temp\Parent Dir With Space\myfile.txt"
ParentDir is Parent Dir With Space
Ce qui précède fonctionne en remplaçant les espaces par des deux points (ceux-ci ne doivent pas exister dans les chemins Windows), puis en remplaçant les séparateurs de répertoires par des espaces afin que les répertoires individuels soient passés à getparentdir en tant qu'arguments séparés. La fonction getparentdir boucle jusqu'à trouver son dernier argument. Enfin, tous les deux-points du résultat sont remplacés par des espaces.
Il peut être très simple d’obtenir le dossier parent du fichier batch:
@echo off
for %%a in ("%~dp0\.") do set "parent=%%~nxa"
echo %parent%
Et pour un parent d'un chemin de fichier selon la question:
@echo off
for %%a in ("c:\test\pack\a.txt") do for %%b in ("%%~dpa\.") do set "parent=%%~nxb"
echo %parent%
L'idée de DaDummy a fonctionné dans des fonctions réutilisables plus pratiques. De plus, le premier caractère de _full_path est maintenant inclus.
set map=D:\test1\test2\test3\test4.txt
call:get_parent_path "%map%"
echo full_path is %_full_path%
call:get_parent_path %_full_path%
echo full_path is %_full_path%
call:get_last_path %_full_path%
echo last_path is %_last_path%
goto :eof
:get_parent_path
set "_full_path=%~dp1"
:_strip
if not "%_full_path:~-1%"=="\" if not "%_full_path:~-1%"=="/" goto:_strip_end
set "_full_path=%_full_path:~0,-1%"
goto:_strip
:_strip_end
exit /b
:get_last_path
set "_last_path=%~nx1"
exit /b
::result:
::full_path is D:\test1\test2\test3
::full_path is D:\test1\test2
::last_path is test2
J'ai trouvé cette combinaison d'approches des réponses du djangofan et du paranoïaque à la fois simple et parfaitement suffisante, lors de la recherche du répertoire parent de mon script:
set FULL_PATH=%~dp0
set FULL_PATH=%FULL_PATH:~1,-1%
for %%i in ("%FULL_PATH%") do set "PARENT_FOLDER=%%~ni"
echo %PARENT_FOLDER%
Etant donné que vous souhaitez plutôt travailler sur les entrées utilisateur, vous devez effectuer un travail supplémentaire minimal, afin de gérer des variantes légales telles que C:\foo\bar\a.txt ou C:\foo\bar\a.txt ou c:/foo/bar/a.txt. Cela pourrait alors fonctionner pour vous:
@setlocal
@echo off
call:GET_PARENT_FOLDER C:\foo\bar\a.txt
echo %PARENT_FOLDER%
call:GET_PARENT_FOLDER C:\foo\bar\\a.txt
echo %PARENT_FOLDER%
call:GET_PARENT_FOLDER c:/foo/bar/a.txt
echo %PARENT_FOLDER%
pause
goto:EOF
:GET_PARENT_FOLDER
:: Strip the filename, so we get something like this: 'C:\foor\bar\'
set "_FULL_PATH=%~dp1"
:: Strips all dangling '\' and '/' in a loop, so the last folder name becomes accessible
:_STRIP
if not "%_FULL_PATH:~-1%"=="\" if not "%_FULL_PATH:~-1%"=="/" goto:_STRIP_END
set "_FULL_PATH=%_FULL_PATH:~1,-1%"
goto:_STRIP
:_STRIP_END
:: We need the context of a for-loop for the special path operators to be available
for %%i in ("%_FULL_PATH%") do set "PARENT_FOLDER=%%~ni"
goto:EOF
vous pouvez utiliser un script vbs, par exemple, enregistrez le ci-dessous sous le nom getpath.vbs
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objArgs = WScript.Arguments
strFile = objArgs(0)
WScript.Echo objFS.GetParentFolderName(strFile)
puis en ligne de commande ou dans votre lot, faites ceci
C:\test>cscript //nologo getpath.vbs c:\test\pack\a.txt
c:\test\pack
Si vous voulez une méthode batch, vous pouvez regarder for /?
.
%~fI - expands %I to a fully qualified path name
%~dI - expands %I to a drive letter only
%~pI - expands %I to a path only
Voici un moyen qui n'utilise pas CALL
et qui, à mon avis, est plus rapide . basé sur la fonction de division de jeb } _ (peut échouer si le nom du répertoire contient !
):
@echo off
set "mydir=%~p1"
SET mydir=%mydir:~0,-1%
setlocal EnableDelayedExpansion
set LF=^
rem ** Two empty lines are required
for %%L in ("!LF!") DO (
set "dir_name=!mydir:\=%%L!"
)
for /f "delims=" %%P in (""!dir_name!"") do set "dn=%%~P"
echo %dn%
exit /b 0
Voici une autre solution:
SET LAST=%CD%
SET PARENTNAME=NONE
cd /D C:\test\pack
FOR %%I in (%CD%) do SET PARENTNAME=%%~nI
cd /D %LAST%
ECHO %PARENTNAME%
%% ~ nI: '~ n' extrait le nom du chemin stocké dans la variable %% I
cd: ajout du paramètre '/ D' pour basculer d'un disque à l'autre