解决从相对路径和/或文件名绝对路径(Resolve absolute path from relat

2019-09-02 08:35发布

有没有在Windows批处理脚本的方式来从包含文件名和/或相对路径返回一个值的绝对路径?

鉴于:

"..\"
"..\somefile.txt"

我需要绝对相对于该批处理文件的路径。

例:

  • “somefile.txt” 位于 “C:\富\”
  • “test.bat的” 位于 “C:\富\酒吧”。
  • 用户打开一个命令行窗口中的“C:\富”,并呼吁Bar\test.bat ..\somefile.txt
  • 在批处理文件“C:\富\ somefile.txt”将衍生自%1

Answer 1:

在批处理文件,如标准的C程序,参数0包含路径到当前执行脚本。 您可以使用%~dp0只得到第0参数的路径部分(这是当前脚本) -这条道路始终是一个完全合格的路径。

您也可以通过让你的第一个参数的完全合格的路径%~f1 ,但根据当前的工作目录,这显然不是你想要的这个给出了一个路径。

就个人而言,我经常使用%~dp0%~1成语在我的批处理文件,该文件第一部分相对于执行批处理的路径参数解释。 它有一个缺点是:如果第一个参数是完全合格它悲惨的失败了。

如果你需要同时支持相对绝对路径,你可以利用的弗雷德里克·梅内斯的解决方案 :临时改变当前的工作目录。

这里是一个将展示各自这些技术的一个例子:

@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

如果这个保存为C:\ TEMP \ example.bat并从C运行:\用户\公用如

C:\用户\公用> \ TEMP \ example.bat .. \ WINDOWS

...你会看到以下的输出:

%~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"


Answer 2:

今天早上我碰到类似的需要来:如何将相对路径转换为Windows命令脚本中的绝对路径。

下面的伎俩:

@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%


Answer 3:

大多数这些问题的答案似乎过于复杂和超级越野车疯了,这里是我的-它适用于任何环境变量,无需%CD%PUSHD / POPD ,或for /f废话-只是普通的老批号等功能。 - 目录和文件甚至不必存在。

CALL :NORMALIZEPATH "..\..\..\foo\bar.txt"
SET BLAH=%RETVAL%

ECHO "%BLAH%"

:: ========== FUNCTIONS ==========
EXIT /B

:NORMALIZEPATH
  SET RETVAL=%~dpfn1
  EXIT /B


Answer 4:

而不必有另一个批处理文件将参数传递给(和使用参数运营商),您可以用FOR /F

FOR /F %%i IN ("..\relativePath") DO echo absolute path: %%~fi

其中i%%~fi是在定义的变量/F %%i 。 例如。 如果你改变了对/F %%a则最后部分将%%~fa

要做到同样的事情就在命令提示符(而不是在一个批处理文件)替换%%% ...



Answer 5:

这是为了帮助填补了阿德里安Plisson的答案(应该只要他编辑它;-) upvoted的差距:

您还可以通过使用%〜F1得到你的第一个参数的完全合格的路径,但根据目前的路径,这显然不是你想要的这个给出了一个路径。

不幸的是,我不知道如何将2混合在一起...

一个可以处理%0%1同样:

  • %~dpnx0的批处理文件本身的完全合格的驱动器+路径+名称+扩展,
    %~f0也足够了;
  • %~dpnx1为完全合格的驱动器+路径+姓名+第一个参数的扩展[如果这是一个文件名都]
    %~f1也足够了;

%~f1将独立工作,你是如何做到指定的第一个参数:相对路径或绝对路径(如果不指定文件的扩展名,当命名%1 ,它不会被添加,即使您使用%~dpnx1 - 但是。

但是,如何在地球上,你会说出不同的驱动器上的文件无论如何,如果你不给就摆在首位的命令行是完整路径信息?

然而, %~p0%~n0%~nx0%~x0可以派上用场了,你应该关心路径(无驱动器号),文件名(不含扩展名),文件全名以扩展或只有文件扩展名。 但要注意,虽然%~p1%~n1将努力找出第一个参数的路径或名称, %~nx1%~x1不会增加+显示扩展名,除非你使用它的命令行了。



Answer 6:

您也可以使用批处理功能如下:

@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


Answer 7:

小改进BrainSlugs83的优秀的解决方案 。 广义允许在呼叫命名输出环境变量。

@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

如果从运行C:\project输出为:

C:\project\doc\build


Answer 8:

我还没有看到这个问题的许多解决方案。 一些解决方案使用CD利用目录遍历和他人利用批处理功能。 我个人的偏好已经批量功能,尤其是MakeAbsolute功能的由DosTips提供。

该函数有一些实实在在的好处,主要是它不改变当前的工作目录,其次是被评估的路径,甚至不必存在。 你可以找到关于如何使用该功能的一些有用的技巧在这里了。

下面是一个例子脚本及其输出:

@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

和输出:

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

我希望这有助于...这肯定又帮我:) PS感谢DosTips! 你摇滚!



Answer 9:

在你的榜样,从酒吧\ test.bat的,DIR / B / S .. \ somefile.txt将返回完整路径。



Answer 10:

您只需将它们连接起来。

SET ABS_PATH=%~dp0 
SET REL_PATH=..\SomeFile.txt
SET COMBINED_PATH=%ABS_PATH%%REL_PATH%

它看起来很奇怪与\ .. \在路中间,但它的工作原理。 无需做任何疯狂的:)



Answer 11:

PowerShell是这些天很常见的,所以我用它经常作为一个快速的方式来调用C#,因为这对几乎所有的功能:

@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%

这是一个有点慢,但获得的功能是很难被击败,除非不诉诸到实际的脚本语言。



Answer 12:

斯泰恩的解决方案包括子文件夹下的作品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%


Answer 13:

文件显示所有其他的答案

目录

随着..是你的相对路径,并假设您目前在D:\Projects\EditorProject

cd .. & cd & cd EditorProject (相对路径)

返回绝对路径如

D:\Projects



Answer 14:

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


文章来源: Resolve absolute path from relative path and/or file name