2016-09-17 1 views
0

Ich habe ein Batch-Skript in Windows ausgeführt. Jedes Mal, wenn das Stapelscript aufgerufen wird, wird ein Eingabepfad als Parameter bereitgestellt. Ich muss den Ordnernamen aus dem Pfad extrahieren. Dafür muss ich den letzten Index von "/" aus dem Pfad abrufen und dann einen Teilstring von diesem Pfad bis zum Ende des Strings nehmen.Letzter Index eines Zeichens in einer Eingabezeichenfolge in einer Batch-Datei

Angenommen, ich habe eine Zeichenfolge/home/home1/home2/home3

Der Ausgang Ich benötige ist home3. Gibt es eine Möglichkeit, dasselbe zu extrahieren?

+0

In Windows sollten Sie den Backslash als Pfadtrennzeichen verwenden, da einige Befehle sonst Probleme haben könnten ... – aschipfl

+0

Möchten Sie _Der letzte Index von "/" aus dem Pfad_ oder Sie wollen _Der letzte Ordnername aus dem Pfad_? Der Fragetitel zeigt an, dass die wichtigen Daten der _index eines Charakters_ sind, aber der letzte Ordner _kann extrahiert werden, ohne einen Index zu verwenden! Ich schlage vor, dass Sie Ihre Fragen auf das _real Problem_ (wie "Ordnername") konzentrieren und nicht zusammenhängende Daten (wie "Index eines Char") einfügen. – Aacini

Antwort

2

Für Ebene DOS/Windows-Batch-Dateien, sollte diese Arbeit:

set FILE="c:\foo\bar.txt" 
for /F %%i in ("%FILE%") do @echo %%~ni 

Das kommt von DOS BAT file equivalent to Unix basename command?

Windows Powershell und der Unix-Shell bieten andere Alternativen.

+0

Danke Todd! :) –

+1

Die '/ F'-Option ist nicht notwendig ... – aschipfl

+0

Nicht nur/F ist nicht notwendig, es wird Probleme verursachen, wenn der Pfad Leerzeichen enthält, es sei denn, DELIMS ist auf nichts gesetzt. Außerdem sollte es "%% ~ nxi" sein, da Ordnernamen Punkte enthalten können. – dbenham

0

Sie haben also eine Zeichenfolge, die einen Ordnerpfad darstellt, und Sie möchten den Namen des am weitesten rechts liegenden Ordners innerhalb des Pfads haben. CMD.EXE bietet komfortable Tools für die Arbeit mit Datei-/Ordnerpfaden, so dass Sie nicht nach dem letzten \ suchen müssen.

Sie geben nicht an, wo sich die Zeichenfolge befindet. Am wahrscheinlichsten ist es entweder 1) in einem Batch-Parameter von einem CALL zu einem Batch-Skript oder: Funktion oder 2) innerhalb einer Umgebungsvariablen. Ich nehme einen Parameter an und zeige eine Abfolge von Lösungen, von denen jede besser (robuster) als die vorherige ist. Am Ende werde ich eine kleine Wendung zeigen, um mich an die Arbeit mit einer Umgebungsvariablen anzupassen. Wenn der Parameter %1/home/home1/home2/home3 enthält, dann brauchen Sie nur %~n1.

Ordnernamen können jedoch Punkte enthalten, und der Text nach dem letzten Punkt wird als Erweiterung betrachtet. Sie brauchen also den Modifikator x, um die Erweiterung einzuschließen. Wenn zum Beispiel %1/home.1/home.2/home.3 enthält, ergibt %~nxhome.3. Es funktioniert genauso gut, wenn es keine Erweiterung gibt.

Ordner-Namen können jedoch ein Giftzeichen wie & enthalten, daher sollten Sie die Zeichenfolge in Anführungszeichen einschließen: "%~nx1". Wenn Sie das Ergebnis einer Variablen zuweisen, sollten Sie die gesamte Zuweisung in Anführungszeichen setzen: set "folder=%~nx1". Der Wert enthält keine Anführungszeichen. Achten Sie also darauf, beim Erweitern der Variablen Anführungszeichen hinzuzufügen: "%folder%", oder verwenden Sie die verzögerte Erweiterung !folder!.

Aber manchmal Leute enthalten einen abschließenden umgekehrten Schrägstrich beim Übergeben eines Ordnerpfads, wie in \home1\home2\home3\. Der abschließende Backslash zeigt an, dass der Pfad zu einem Ordner ist, aber %~nx1 wird nichts ergeben. Es gibt einen einfachen Trick mit einer FOR-Schleife und einem angehängten Punkt, um dies zu lösen.

for %%F in (%1.) do set "folder=%%~nxF" 

Beachten Sie, dass FOR-Variablen genau dieselben Modifikatoren wie Parameter verwenden. Der angefügte Punkt löst elegant das Problem auf eine knifflige Art und Weise. Wenn es einen abschließenden Backslash gibt, dann repräsentiert der Punkt das "aktuelle" Verzeichnis von dieser Position. Die Erweiterungsmodifikatoren normalisieren das Ergebnis automatisch in eine kanonische Form, die die richtige Antwort liefert. Aber es funktioniert auch, wenn es keinen abschließenden Backslash gibt. Datei- und Ordnernamen dürfen nicht mit einem Punkt oder einem Leerzeichen enden, und die Expansionsnormierung entfernt den nachfolgenden Punkt.

Es gibt einige andere esoterische Fälle, die sich mit UNC-Pfaden und langen Pfaden befassen, die durch Hinzufügen des ~f-Modifikators zum Konvertieren von %1 in den vollständigen kanonischen Pfad gelöst werden.

Hier ist die ultimative Lösung, die "immer" mit Batch-Parameter %1 arbeiten sollte.

for %%F in ("%~f1.") do set "folder=%%~nxF" 

Ich habe das Wort „immer“ in Anführungszeichen, weil es möglich ist, den Code zu scheitern, aber es würde den Endbenutzer, etwas zu tun dumm wie vorbei "c:\This"^&"that\" erfordern. In diesem Fall ist die richtige Vorgehensweise einfach zu übergeben.

Beachten Sie, dass der übergebene Pfad die Wurzel eines Volumes sein könnte, wie "c: \". In diesem Fall ist das Ergebnis eine leere Zeichenfolge, die korrekt ist - es gibt keinen Ordnernamen.

Wie mit einer Umgebungsvariablen haben, anstatt arbeiten Sie

Angenommen Variable folderPath, die den Pfad-Zeichenfolge enthält. Wenn Sie wissen, dass der Wert keine Anführungszeichen enthält, und es ist kein UNC oder langer Pfad, dann können Sie einfach:

for %%F in ("%folderPath%.") do set "folder=%%~nxF" 

Aber das kann auf vielfältige Weise fehlschlagen, wenn der Wert bereits Angebote enthält, oder wenn es ein UNC oder ein langer Weg ist. Die Lösung besteht darin, eine zusätzliche FOR/F-Schleife hinzuzufügen, die mit einer verzögerten Erweiterung gekoppelt ist, um den Wert sicher in eine FOR-Variable zu übertragen. Dann kann der Modifikator ~f wie zuvor verwendet werden. Pfade können jedoch das Zeichen ! enthalten, und bei der Variablenerweiterung FOR wird die Option ! entfernt, wenn die verzögerte Erweiterung aktiviert ist. Daher muss die verzögerte Expansion strategisch ein- und ausgeschaltet werden.

Hier ist die ultimative Lösung für die Arbeit mit einer variablen

Ich gehe davon aus, dass eine verzögerte Expansion derzeit ausgeschaltet ist.

setlocal enableDelayedExpansion 
for /f "eol=: delims=" %%A in ("!folderPath!") do (
    endlocal 
    for %%F in ("%%~fA.") do set "folder=%%~nxF" 
) 

Mir sind keine Szenarien bekannt, in denen dieser letzte Code fehlschlagen kann.

Verwandte Themen