Résoudre chemin absolu de chemin relatif et/ou nom de fichier
y a-t-il un moyen dans un script Windows batch de retourner un chemin absolu à partir d'une valeur contenant un nom de fichier et/ou un chemin relatif?
donnée:
".."
"..somefile.txt"
j'ai besoin du chemin absolu par rapport au fichier batch.
exemple:
- "unfichier.txt " est situé dans "C:Foo "
- " test.chauve-souris" est situé dans "C:FooBar".
- L'utilisateur ouvre une fenêtre de commande dans "C:Foo" et appelle
Bartest.bat ..somefile.txt
- dans le fichier batch "C:Foosomefile.txt" serait dérivé de
%1
14 réponses
dans les fichiers batch, comme dans les programmes C standard, l'argument 0 contient le chemin du script en cours d'exécution. Vous pouvez utiliser %~dp0
pour obtenir seulement la partie chemin du 0ème argument (qui est le script courant) - ce chemin est toujours un chemin entièrement qualifié.
vous pouvez également obtenir le chemin entièrement qualifié de votre premier argument en utilisant %~f1
, mais cela donne un chemin selon le répertoire de travail courant, qui n'est évidemment pas ce que vous voulez.
personnellement, j'utilise souvent l'idiome %~dp0%~1
dans mon fichier batch, qui interprète le premier argument relatif au chemin du lot d'exécution. Il a un défaut: il échoue lamentablement si le premier argument est complet.
si vous avez besoin de supporter à la fois les chemins absolus relatifs et , vous pouvez faire usage de solution de Frédéric Ménez : changer temporairement le fonctionnement actuel répertoire.
voici un exemple qui démontrera chacune de ces techniques:
@echo off
echo %%~dp0 is "%~dp0"
echo %%0 is "%0"
echo %%~dpnx0 is "%~dpnx0"
echo %%~f1 is "%~f1"
echo %%~dp0%%~1 is "%~dp0%~1"
rem Temporarily change the current working directory, to retrieve a full path
rem to the first parameter
pushd .
cd %~dp0
echo batch-relative %%~f1 is "%~f1"
popd
si vous sauvegardez ceci comme c:\temp\example.chauve-souris et de les exécuter à partir de c:\Users\Public
c:\Users\Public > \temp \ example.chauve. .\windows
...vous observerez la sortie suivante:
%~dp0 is "C:\temp\"
%0 is "\temp\example.bat"
%~dpnx0 is "C:\temp\example.bat"
%~f1 is "C:\Users\windows"
%~dp0%~1 is "C:\temp\..\windows"
batch-relative %~f1 is "C:\Windows"
j'ai rencontré un besoin similaire ce matin: comment convertir un chemin relatif en un chemin absolu à l'intérieur d'un script de commande Windows.
a fait le tour:
@echo off
set REL_PATH=..\..\
set ABS_PATH=
rem // Save current directory and change to target directory
pushd %REL_PATH%
rem // Save value of CD variable (current directory)
set ABS_PATH=%CD%
rem // Restore original directory
popd
echo Relative path: %REL_PATH%
echo Maps to path: %ABS_PATH%
la plupart de ces réponses semblent folles au-dessus du buggy compliqué et super, voici le mien -- il fonctionne sur n'importe quelle variable d'environnement, Pas de %CD%
ou PUSHD
/ POPD
, ou for /f
non-sens -- juste de vieilles fonctions de fournée simples. -- Le répertoire et le fichier n'ont même pas besoin d'exister.
CALL :NORMALIZEPATH "..\..\..\foo\bar.txt"
SET BLAH=%RETVAL%
ECHO "%BLAH%"
:: ========== FUNCTIONS ==========
EXIT /B
:NORMALIZEPATH
SET RETVAL=%~dpfn1
EXIT /B
sans avoir à avoir un autre fichier batch pour passer des arguments à (et utiliser les opérateurs d'argument), vous pouvez utiliser FOR /F
:
FOR /F %%i IN ("..\relativePath") DO echo absolute path: %%~fi
où i
dans %%~fi
est la variable définie à /F %%i
. par exemple. si vous avez changé cela en /F %%a
alors la dernière partie serait %%~fa
.
pour faire la même chose directement à l'invite de commande (et non dans un fichier de lot) remplacer %%
par %
...
ceci est pour aider à combler les lacunes dans la réponse D'Adrien Plisson (qui devrait être révoquée dès qu'il l'édite; -):
vous pouvez également obtenir le chemin entièrement qualifié de votre premier argument en utilisant %~f1, mais cela donne un chemin selon le chemin courant, qui n'est évidemment pas ce que vous voulez.
malheureusement, je ne sais pas comment mélanger les deux...
on peut manipuler %0
et %1
de même:
-
%~dpnx0
pour entraînement entièrement qualifié+chemin+Nom+extension du fichier batch lui-même,
%~f0
-
%~dpnx1
pour lecteur pleinement qualifié+chemin+Nom+extension de son premier argument [si c'est un nom de fichier],
%~f1
%~f1
"fonctionnera indépendamment de la façon dont vous avez spécifié votre premier argument: avec des chemins relatifs ou avec des chemins absolus (si vous ne spécifiez pas l'extension du fichier lors de la dénomination %1
, il ne sera pas ajouté, même si vous utilisez %~dpnx1
-- cependant.
mais comment diable nommeriez-vous un fichier sur un lecteur différent de toute façon si vous ne donneriez pas ces informations complètes de chemin sur la ligne de commande en premier lieu?
cependant, %~p0
, %~n0
, %~nx0
et %~x0
peut s'avérer pratique, si vous êtes intéressé par le chemin (sans driveletter), le nom du fichier (sans extension), le nom complet du fichier avec extension ou l'extension du nom du fichier seulement. Mais notez, alors que %~p1
et %~n1
fonctionneront pour trouver le chemin ou le nom du premier argument, %~nx1
et %~x1
n'ajouteront pas+afficher l'extension, à moins que vous ne l'ayez déjà utilisé sur la ligne de commande.
vous pouvez également utiliser des fonctions par lots pour cela:
@echo off
setlocal
goto MAIN
::-----------------------------------------------
:: "%~f2" get abs path of %~2.
::"%~fs2" get abs path with short names of %~2.
:setAbsPath
setlocal
set __absPath=%~f2
endlocal && set %1=%__absPath%
goto :eof
::-----------------------------------------------
:MAIN
call :setAbsPath ABS_PATH ..\
echo %ABS_PATH%
endlocal
je n'ai pas vu beaucoup de solutions à ce problème. Certaines solutions utilisent le répertoire transversal en utilisant le CD et d'autres utilisent les fonctions batch. Ma préférence personnelle a été pour les fonctions de fournée et en particulier, le MakeAbsolute fonction telle que fournie par DosTips.
la fonction a quelques avantages réels, principalement qu'elle ne change pas votre répertoire de travail actuel et deuxièmement que les chemins évalués n'ont même pas à exister. Vous pouvez trouver quelques conseils utiles sur la façon d'utiliser la fonction ici .
voici un exemple de script et de ses sorties:
@echo off
set scriptpath=%~dp0
set siblingfile=sibling.bat
set siblingfolder=sibling\
set fnwsfolder=folder name with spaces\
set descendantfolder=sibling\descendant\
set ancestorfolder=..\..\
set cousinfolder=..\uncle\cousin
call:MakeAbsolute siblingfile "%scriptpath%"
call:MakeAbsolute siblingfolder "%scriptpath%"
call:MakeAbsolute fnwsfolder "%scriptpath%"
call:MakeAbsolute descendantfolder "%scriptpath%"
call:MakeAbsolute ancestorfolder "%scriptpath%"
call:MakeAbsolute cousinfolder "%scriptpath%"
echo scriptpath: %scriptpath%
echo siblingfile: %siblingfile%
echo siblingfolder: %siblingfolder%
echo fnwsfolder: %fnwsfolder%
echo descendantfolder: %descendantfolder%
echo ancestorfolder: %ancestorfolder%
echo cousinfolder: %cousinfolder%
GOTO:EOF
::----------------------------------------------------------------------------------
:: Function declarations
:: Handy to read http://www.dostips.com/DtTutoFunctions.php for how dos functions
:: work.
::----------------------------------------------------------------------------------
:MakeAbsolute file base -- makes a file name absolute considering a base path
:: -- file [in,out] - variable with file name to be converted, or file name itself for result in stdout
:: -- base [in,opt] - base path, leave blank for current directory
:$created 20060101 :$changed 20080219 :$categories Path
:$source http://www.dostips.com
SETLOCAL ENABLEDELAYEDEXPANSION
set "src=%~1"
if defined %1 set "src=!%~1!"
set "bas=%~2"
if not defined bas set "bas=%cd%"
for /f "tokens=*" %%a in ("%bas%.\%src%") do set "src=%%~fa"
( ENDLOCAL & REM RETURN VALUES
IF defined %1 (SET %~1=%src%) ELSE ECHO.%src%
)
EXIT /b
et la sortie:
C:\Users\dayneo\Documents>myscript
scriptpath: C:\Users\dayneo\Documents\
siblingfile: C:\Users\dayneo\Documents\sibling.bat
siblingfolder: C:\Users\dayneo\Documents\sibling\
fnwsfolder: C:\Users\dayneo\Documents\folder name with spaces\
descendantfolder: C:\Users\dayneo\Documents\sibling\descendant\
ancestorfolder: C:\Users\
cousinfolder: C:\Users\dayneo\uncle\cousin
j'espère que cela aidera... Il m'a aidé :) P. S. Merci encore à DosTips! Vous rock!
Petite amélioration à BrainSlugs83 est une excellente solution . Généralisé pour permettre de nommer la variable d'environnement de sortie dans l'appel.
@echo off
setlocal EnableDelayedExpansion
rem Example input value.
set RelativePath=doc\build
rem Resolve path.
call :ResolvePath AbsolutePath %RelativePath%
rem Output result.
echo %AbsolutePath%
rem End.
exit /b
rem === Functions ===
rem Resolve path to absolute.
rem Param 1: Name of output variable.
rem Param 2: Path to resolve.
rem Return: Resolved absolute path.
:ResolvePath
set %1=%~dpfn2
exit /b
si l'exécution de C:\project
sortie est:
C:\project\doc\build
dans votre exemple, de Bar\test.bat, DIR / B / s..\somefile.txt retournerait le chemin complet.
vous pouvez les concaténer.
SET ABS_PATH=%~dp0
SET REL_PATH=..\SomeFile.txt
SET COMBINED_PATH=%ABS_PATH%%REL_PATH%
il semble étrange avec \..\ dans le milieu de votre chemin, mais il fonctionne. Pas besoin de faire quelque chose de fou :)
PowerShell est assez commun ces jours-ci donc je l'utilise souvent comme un moyen rapide d'invoquer C# Depuis qui a des fonctions pour à peu près tout:
@echo off
set pathToResolve=%~dp0\..\SomeFile.txt
for /f "delims=" %%a in ('powershell -Command "[System.IO.Path]::GetFullPath( '%projectDirMc%' )"') do @set resolvedPath=%%a
echo Resolved path: %resolvedPath%
c'est un peu lent, mais la fonctionnalité gagnée est difficile à battre à moins que sans recourir à un langage de script réel.
stijn de la solution fonctionne avec des sous-dossiers de C:\Program Files (86)\
,
@echo off
set projectDirMc=test.txt
for /f "delims=" %%a in ('powershell -Command "[System.IO.Path]::GetFullPath( '%projectDirMc%' )"') do @set resolvedPath=%%a
echo full path: %resolvedPath%
Files voir toutes les autres réponses
annuaires
avec ..
étant votre chemin relatif, et en supposant que vous êtes actuellement dans D:\Projects\EditorProject
:
cd .. & cd & cd EditorProject
(le chemin relatif)
renvoie le chemin absolu par exemple
D:\Projects
SET CD=%~DP0
SET REL_PATH=%CD%..\..\build\
call :ABSOLUTE_PATH ABS_PATH %REL_PATH%
ECHO %REL_PATH%
ECHO %ABS_PATH%
pause
exit /b
:ABSOLUTE_PATH
SET %1=%~f2
exit /b