Gibt es in einem Windows-Batch-Skript 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 Batch-Datei.
Beispiel:
- "somefile.txt" befindet sich in "C: \ Foo \"
- "test.bat" befindet sich in "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" von abgeleitet
%1
windows
batch-file
relative-path
absolute-path
Nathan Taylor
quelle
quelle
realpath
für eine robuste Pfadnormalisierung.SET FilePath=%CD%\%1
so könnte es seinC:\Foo\Bar\..\..\some\other\dir\file.txt
. Programme scheinen einen so komplizierten Weg zu verstehen.Antworten:
In Batch-Dateien enthält Argument 0 wie in Standard-C-Programmen den Pfad zum aktuell ausgeführten Skript. Sie können
%~dp0
nur den Pfadabschnitt des 0. Arguments abrufen (dies ist das aktuelle Skript). Dieser Pfad ist immer ein vollständig qualifizierter Pfad.Sie können auch den vollständig qualifizierten Pfad Ihres ersten Arguments mithilfe von ermitteln
%~f1
. Dies gibt jedoch einen Pfad entsprechend dem aktuellen Arbeitsverzeichnis an, der offensichtlich nicht Ihren Wünschen entspricht.Persönlich verwende ich häufig das
%~dp0%~1
Idiom in meiner Batch-Datei, das das erste Argument relativ zum Pfad des ausführenden Batches interpretiert. Es hat jedoch ein Manko: Es scheitert kläglich, wenn das erste Argument voll qualifiziert ist.Wenn Sie sowohl relative als auch absolute Pfade unterstützen müssen, können Sie die Lösung von Frédéric Ménez verwenden : Ändern Sie vorübergehend das aktuelle Arbeitsverzeichnis.
Hier ist ein Beispiel, das jede dieser Techniken demonstriert:
Wenn Sie dies als c: \ temp \ example.bat speichern und unter c: \ Users \ Public as ausführen
c: \ Users \ Public> \ temp \ example.bat .. \ windows
... Sie werden die folgende Ausgabe beobachten:
Die Dokumentation zu den Modifikatoren, die für ein Batch-Argument zulässig sind, finden Sie hier: https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/call
quelle
%0
und%1
ebenfalls:%~dpnx0
für vollqualifizierten Pfad + Name der Batch - Datei selbst,%~dpnx1
für den vollqualifizierten Pfad + Name seines ersten Argument [ , ob das eine Dateiname bei allen]. (Aber wie um alles in der Welt würden Sie eine Datei auf einem anderen Laufwerk benennen, wenn Sie diese vollständigen Pfadinformationen sowieso nicht in der Befehlszeile angeben würden?)d:\foo\..\bar\xyz.txt
kann noch normalisiert werden. Ich empfehle, diesen Ansatz mit der folgenden Antwort von @ axel-heider zu verwenden (unter Verwendung einer Batch-Subroutine - dann können Sie dies für jede Variable tun, nicht nur für eine nummerierte Variable).Ich bin heute Morgen auf ein ähnliches Bedürfnis gestoßen: wie man einen relativen Pfad in einen absoluten Pfad innerhalb eines Windows-Befehlsskripts konvertiert.
Folgendes hat den Trick gemacht:
quelle
pushd .
verhindert dieses Problem.Die meisten dieser Antworten scheinen verrückt nach komplizierten und super fehlerhaften zu sein. Hier ist meine - sie funktioniert mit jeder Umgebungsvariablen, ohne
%CD%
oderPUSHD
/POPD
oderfor /f
Unsinn - nur mit alten Batch-Funktionen. - Das Verzeichnis und die Datei müssen nicht einmal vorhanden sein.quelle
%~f1
es nur eine Abkürzung für%~dpfn1
- also zögern Sie nicht, es%~f1
stattdessen zu verwenden . 🙂 - im Langformat~
bedeutet das Entfernen der Anführungszeichen,d
bedeutet Laufwerk,p
bedeutet Pfad,n
allein wäre Dateiname ohne Erweiterung,fn
bedeutet aber Dateiname mit Erweiterung. das1
bedeutet das erste Argument. - (Ich glaube, dieses Format ist älter als Windows 7.)Ohne dass Sie eine andere Batch-Datei benötigen, um Argumente zu übergeben (und die Argumentoperatoren zu verwenden), können Sie Folgendes verwenden
FOR /F
:Dabei ist das
i
in%%~fi
die unter definierte Variable/F %%i
. z.B. Wenn Sie das ändern/F %%a
würden, wäre der letzte Teil%%~fa
.Um dasselbe direkt an der Eingabeaufforderung (und nicht in einer Batch-Datei) zu tun, ersetzen Sie
%%
durch%
...quelle
cd
Befehl die%CD%
Umgebungsvariable nicht unbedingt ändert (wenn Sie beispielsweise auf dem Laufwerk sindD:
und IhrC:
cd /D D:\on.other.drive
FOR /F %%i IN ("..\relativePath") DO echo absolute path: %%~fi
wird fehlschlagen, wenn das..\relativePath
Leerzeichen enthältfor /?
dass die Verwendung von Großbuchstaben für Variablennamen empfohlen wird, um Verwechslungen mit den Substitutionsparametern zu vermeiden/F
funktioniert nicht für nicht vorhandene Pfade und löst Platzhalterzeichen auf. Wenn Sie das wollen, großartig, aber wenn Sie die Funktionalität von wollen/F
, dann müssen Sie nur dastokens
Schlüsselwort verwenden:FOR /F "tokens=*" %%I IN ("..\relative Path\*") DO echo absolute path: %%~fI
Dies soll helfen, die Lücken in Adrien Plissons Antwort zu schließen (die bewertet werden sollte, sobald er sie bearbeitet ;-):
Man kann damit umgehen
%0
und%1
ebenso:%~dpnx0
für vollqualifiziertes Laufwerk + Pfad + Name + Erweiterung der Batchdatei selbst%~f0
reicht ebenfalls aus;%~dpnx1
für vollqualifiziertes Laufwerk + Pfad + Name + Erweiterung des ersten Arguments [wenn das überhaupt ein Dateiname ist],%~f1
reicht ebenfalls aus;%~f1
funktioniert unabhängig davon, wie Sie Ihr erstes Argument angegeben haben: mit relativen Pfaden oder mit absoluten Pfaden (wenn Sie die Dateierweiterung beim Benennen nicht angeben%1
, wird sie nicht hinzugefügt, selbst wenn Sie sie verwenden%~dpnx1
- jedoch.Aber wie um alles in der Welt würden Sie eine Datei auf einem anderen Laufwerk überhaupt benennen, wenn Sie diese vollständigen Pfadinformationen überhaupt nicht in der Befehlszeile angeben würden?
Jedoch
%~p0
,%~n0
,%~nx0
und%~x0
kann sich als nützlich erweisen, sollten Sie in Pfad interessiert sein (ohne Laufwerksbuchstaben), Dateiname (ohne Erweiterung), vollständigen Dateinamen mit der Erweiterung oder nur Dateinamenerweiterung. Beachten Sie jedoch, dass während%~p1
und%~n1
arbeiten Sie, um den Pfad oder Namen des ersten Arguments herauszufinden,%~nx1
und%~x1
fügen Sie die Erweiterung nicht + hinzu, es sei denn, Sie haben sie bereits in der Befehlszeile verwendet.quelle
%~dpnx1
besteht darin, dass der vollständig qualifizierte Pfad des Arguments relativ zum aktuellen Verzeichnis angegeben wird , während das OP den Pfad relativ zu dem Verzeichnis wünscht, in dem sich die Batchdatei befindet .%~dpnx1
gibt den voll qualifizierten Pfad des 1. Arguments an. Nicht in Bezug auf alle, und nicht relativ zum aktuellen Verzeichnis entweder. Dasd
ist für Laufwerk, dasp
ist für Pfad, dasn
ist für Dateiname ohne Suffix, dasx
ist für Suffix, das1
ist für das erste Argument. - Und Nathans Frage war: "Gibt es eine Möglichkeit, einen absoluten Pfad von einem Wert zurückzugeben, der einen Dateinamen und / oder einen relativen Pfad enthält?"Sie können hierfür auch Batch-Funktionen verwenden:
quelle
Kleine Verbesserung der hervorragenden Lösung von BrainSlugs83 . Verallgemeinert, um die Benennung der Ausgabeumgebungsvariablen im Aufruf zu ermöglichen.
Wenn vom
C:\project
Ausgang ausgeführt wird:quelle
Ich habe nicht viele Lösungen für dieses Problem gesehen. Einige Lösungen verwenden das Durchsuchen von Verzeichnissen mithilfe von CD, andere Batch-Funktionen. Meine persönliche Präferenz waren Batch-Funktionen und insbesondere die MakeAbsolute- Funktion von DosTips.
Die Funktion hat einige echte Vorteile, vor allem, dass sie Ihr aktuelles Arbeitsverzeichnis nicht ändert und zweitens, dass die ausgewerteten Pfade nicht einmal vorhanden sein müssen. Sie können ein paar hilfreiche Tipps , wie die Funktion nutzen hier auch.
Hier ist ein Beispielskript und seine Ausgaben:
Und die Ausgabe:
Ich hoffe das hilft ... es hat mir sicher geholfen :) PS Nochmals vielen Dank an DosTips! Du rockst!
quelle
Sie können sie einfach verketten.
es sieht seltsam aus mit \ .. \ in der Mitte Ihres Pfades, aber es funktioniert. Keine Notwendigkeit, etwas Verrücktes zu tun :)
quelle
echo %~dp0..\SomeFile.txt
In Ihrem Beispiel würde DIR / B / S .. \ somefile.txt aus Bar \ test.bat den vollständigen Pfad zurückgeben.
quelle
PowerShell ist heutzutage ziemlich verbreitet, daher verwende ich es oft als schnelle Möglichkeit, C # aufzurufen, da dies Funktionen für so ziemlich alles bietet:
Es ist ein bisschen langsam, aber die gewonnene Funktionalität ist schwer zu übertreffen, wenn nicht auf eine tatsächliche Skriptsprache zurückgegriffen wird.
quelle
Die Lösung von stijn funktioniert mit Unterordnern unter
C:\Program Files (86)\
,quelle
Dateien Alle anderen Antworten anzeigen
Verzeichnisse
Mit
..
Ihrem relativen Pfad und der Annahme, dass Sie sich gerade inD:\Projects\EditorProject
:cd .. & cd & cd EditorProject
(der relative Pfad)gibt den absoluten Pfad zurück, z
D:\Projects
quelle
quelle