Frage

Gibt es in einem Windows-Batchskript eine Möglichkeit, einen absoluten Pfad von einem Wert zurückzugeben, der einen Dateinamen und/oder einen relativen Pfad enthält?

Gegeben:

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

Ich brauche den absoluten Pfad relativ zur Batchdatei.

Beispiel:

  • „somefile.txt“ befindet sich in „C:\Foo\“
  • „test.bat“ befindet sich unter „C:\Foo\Bar“.
  • Der Benutzer öffnet ein Befehlsfenster in „C:\Foo“ und ruft auf Bar\test.bat ..\somefile.txt
  • In der Batch-Datei würde „C:\Foo\somefile.txt“ abgeleitet werden %1
War es hilfreich?

Lösung

In Batch-Dateien, wie in Standard-C-Programmen, Argument 0 enthält den Pfad zum aktuell ausgeführten Skripts. Sie %~dp0 verwenden können, nur den Pfad Teil des 0-ten Argument zu bekommen (was das aktuelle Skript ist.) - dieser Weg ist immer ein vollständig qualifizierter Pfad

Sie können auch den vollständigen Pfad des ersten Arguments erhalten, indem %~f1 verwenden, aber dies gibt einen Weg nach dem aktuellen Arbeitsverzeichnis, das ist natürlich nicht das, was Sie wollen.

Ich persönlich verwende oft das %~dp0%~1 Idiom in meiner Batch-Datei, die den ersten Argument in Bezug auf den Pfad des Vollstreckungs Batch interpretieren. Es hat einen Mangel, obwohl. Es scheitert kläglich, wenn das erste Argument voll qualifiziert ist,

Wenn Sie beide relativ unterstützen müssen und absolute Pfade, können Sie die Verwendung von Frédéric Ménez Lösung: vorübergehend das aktuelle Arbeitsverzeichnis ändern.

Hier ist ein Beispiel, dass jede dieser Techniken demonstrieren werden:

@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

Wenn Sie diese speichern unter c: \ temp \ example.bat und führen Sie es von c: \ Benutzer \ Öffentlich als

c: \ Benutzer \ Öffentlich> \ temp \ example.bat .. \ windows

... Sie werden die folgende Ausgabe beachten:

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

die Dokumentation für den Satz von Modifikatoren auf einem Batch-Argumente erlaubt ist hier zu finden: https://docs.microsoft.com/en- us / windows-server / Verwaltung / windows-Befehle / rufen

Andere Tipps

Ich kam in einem ähnlichen Bedürfnisse an diesen Morgen: wie man einen relativen Pfad in einen absoluten Pfad in einer Windows-Befehlsskript konvertieren

.

Im Folgenden hat den Trick:

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

Die meisten dieser Antworten scheinen verrückt über komplizierten und Super-Buggy, hier ist meins - es funktioniert auf jedem Umgebungsvariable, ohne %CD% oder PUSHD / POPD oder for /f Unsinn - einfach nur alte Batch-Funktionen. -. Das Verzeichnis & Datei hat nicht einmal existieren

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

ECHO "%BLAH%"

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

:NORMALIZEPATH
  SET RETVAL=%~dpfn1
  EXIT /B

Ohne eine andere Batch-Datei zu haben, Argumente zu übergeben (und verwenden Sie das Argument Operatoren), Sie FOR /F verwenden können:

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

, wo der i in %%~fi die Variablen bei /F %%i definiert ist. z.B. wenn du das geändert /F %%a dann der letzte Teil %%~fa würde.

die gleiche Recht an der Eingabeaufforderung zu tun (und nicht in einer Batch-Datei) ersetzen %% mit % ...

Dies soll dazu beitragen, die Lücken in Adrien Plissons Antwort zu schließen (die positiv bewertet werden sollte, sobald er sie bearbeitet ;-):

Sie können den vollständig qualifizierten Pfad Ihres ersten Arguments auch erhalten, indem Sie %~f1 verwenden. Dies ergibt jedoch einen Pfad, der dem aktuellen Pfad entspricht, was offensichtlich nicht das ist, was Sie wollen.

Leider weiß ich nicht, wie ich die beiden zusammenmischen soll ...

Man kann damit umgehen %0 Und %1 ebenfalls:

  • %~dpnx0 für vollständig qualifiziertes Laufwerk+Pfad+Name+Erweiterung der Batchdatei selbst,
    %~f0 reicht auch;
  • %~dpnx1 für vollqualifiziertes Laufwerk+Pfad+Name+Erweiterung seines ersten Arguments [falls das überhaupt ein Dateiname ist],
    %~f1 reicht auch;

%~f1 funktioniert unabhängig davon, wie Sie Ihr erstes Argument angegeben haben:mit relativen Pfaden oder mit absoluten Pfaden (wenn Sie bei der Benennung nicht die Dateierweiterung angeben). %1, wird es nicht hinzugefügt, auch wenn Sie es verwenden %~dpnx1 -- Jedoch.

Aber wie um alles in der Welt würde man einer Datei einen Namen geben? auf einem anderen Laufwerk Wie auch immer, wenn Sie die vollständigen Pfadinformationen nicht von vornherein in der Befehlszeile angeben würden?

Jedoch, %~p0, %~n0, %~nx0 Und %~x0 kann nützlich sein, wenn Sie sich für den Pfad (ohne Laufwerksbuchstaben), den Dateinamen (ohne Erweiterung), den vollständigen Dateinamen mit Erweiterung oder nur die Erweiterung des Dateinamens interessieren.Aber beachten Sie, während %~p1 Und %~n1 wird arbeiten, um den Pfad oder Namen des ersten Arguments herauszufinden, %~nx1 Und %~x1 fügt die Erweiterung nicht hinzu und zeigt sie nicht an, es sei denn, Sie haben sie bereits in der Befehlszeile verwendet.

Sie können auch Batch-Funktionen für diese verwenden:

@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

Kleine Verbesserung BrainSlugs83 ausgezeichnete Lösung . Verallgemeinerte zu ermöglichen, das Ausgangs-Umgebungsvariable in dem Aufruf zu nennen.

@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

Wenn Lauf von C:\project Ausgabe lautet:

C:\project\doc\build

Ich habe nicht viele Lösungen für dieses Problem zu sehen. Einige Lösungen nutzen Directory-Traversal mit CD und anderer Verwendung von Batch-Funktionen machen. Meine persönliche Präferenz ist für Batch-Funktionen gewesen und insbesondere die MakeAbsolute Funktion als vorgesehen von DosTips.

Die Funktion hat einige echten Vorteile, vor allem, dass es nicht Ihr aktuelles Arbeitsverzeichnis ändert, und zweitens, dass die Pfade existieren nicht einmal ausgewertet. Sie können ein paar hilfreiche Tipps, wie Sie die Funktion verwenden hier zu.

Hier ist ein Beispiel-Script und seine Ausgänge:

@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

Und die Ausgabe:

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

Ich hoffe, das hilft ... Es ist sicher mir geholfen :) P. S. Nochmals vielen Dank an DosTips! Sie schaukeln!

In Ihrem Beispiel von Bar \ test.bat, DIR / B / S .. \ somefile.txt würde den vollständigen Pfad zurückzukehren.

Sie können sie einfach verketten.

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

es sieht seltsam aus mit \ .. \ in der Mitte des Weges, aber es funktioniert. Keine Notwendigkeit, etwas zu tun verrückt:)

Powershell ist in diesen Tagen ziemlich häufig so verwende ich es oft als eine schnelle Art und Weise C # aufrufen, da diese Funktionen für so ziemlich alles hat:

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

Es ist ein bisschen langsam, aber die Funktionalität gewonnen ist hart, wenn nicht zu schlagen, ohne zu einer tatsächlichen Skriptsprache zurückzugreifen.

stijn-Lösung arbeitet mit Unterordner unter 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%

Dateien Alle anderen Antworten

Verzeichnisse

Mit .. Ihr relativer Pfad ist, und vorausgesetzt, Sie zur Zeit in D:\Projects\EditorProject sind:

cd .. & cd & cd EditorProject (der relative Pfad)

liefert absoluten Pfad z.

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top