2014-11-02 6 views
6

Angenommen, ich verfüge über ein Stapelscript, das im Argument %1 einen Ordnerpfad erwartet. Ich möchte einen Dateinamen an den Pfad anhängen und diesen in einem Befehl verwenden. Gibt es eine einfache Möglichkeit, dies in allen Situationen zuverlässig zu tun?Wie kann ein Dateiname an ein Windows-Ordnerpfad-Argument angehängt werden?

Ich möchte nicht PUSHD %1 und ignorieren Sie einfach den Pfad danach. Angenommen, meine Logik erfordert, dass das aktuelle Verzeichnis unverändert bleibt.

Das Problem ist, das %1 Argument kann oder nicht beendet Backslash haben kann - das heißt c:\path oder c:\path\.

Normalerweise kann ich einfach "%~1\file.ext" verwenden, weil Windows "c:\path\file.ext" und "c:\path\\file.ext" identisch behandelt.

Aber es gibt einen bösen Fall - c:\

die folgenden Befehle erzeugen diesen Fehler: The filename, directory name, or volume label syntax is incorrect.

dir "c:\\file.ext" 
del "c:\\file.ext" 

Das Seltsame ist, arbeiten diese Befehle einfach gut:

if exist "c:\\file.ext" echo OK 
echo text>"c:\\file.ext" 
copy "c:\\file.ext" "somePath" 
xcopy "c:\\file.ext" "somePath" 

Es ist ein weiterer problematischer Fall - c:, was bedeutet, das aktuelle Verzeichnis auf Laufwerk C :, wird das falsche Ergebnis geben, wenn ich einen Backslash anhängen. "c:file.ext" ist nicht dasselbe wie "c:\file.ext".

Gibt es eine einfache Möglichkeit, einen Dateinamen an ein bestimmtes Ordnerpfadargument sicher anzuhängen?

Ich bin nicht mit UNC-Pfaden beschäftigt, wie ich sie nicht sehr oft benutze, und ich glaube, es gibt einige Befehle, die nicht gut mit UNC-Pfaden spielen.

Hinweis: Dies ist ein Fall, in dem ich gepaarte Fragen und Antworten posten möchte. Dieses Problem ist seit einigen Jahren ein Dorn in meiner Seite, und ich entdeckte vor kurzem eine einfache Lösung, die ich dachte, andere interessieren könnten

Antwort

6

EDIT -. Antwort geändert MC ND Kommentar zu adressieren

Die Lösung ist so einfach :-) "%~f1.\file.ext"

Windows-Dateinamen nicht mit . oder <space> enden können, so dass alle Windows-Befehle einfach ignorieren . und <space> in Datei-/Ordnernamen Hinter.

Und eine einzige . nach einem umgekehrten Schrägstrich repräsentiert das aktuelle Verzeichnis an dieser Stelle.

Angenommen, das aktuelle Arbeitsverzeichnis ist c:\test, dann ist die Tabelle unten zeigen, wie verschiedene Werte gelöst bekommen:

"%~1"  | "%~f1.\file.ext"  | equivalent to 
-------------+------------------------+------------------------ 
"c:\folder\" | "c:\folder\.\file.ext" | "c:\folder\file.ext" 
      |      | 
"c:\folder" | "c:\folder.\file.ext" | "c:\folder\file.ext" 
      |      | 
"c:\"  | "c:\.\file.ext"  | "c:\file.ext" 
      |      | 
"c:"   | "c:\test.\file.ext" | "c:\test\file.ext" 
      |      | 
"."   | "c:\test.\file.ext" | "c:\test\file.ext" 
      |      | 
".."   | "c:\.\file.ext"  | "c:\file.ext" 
      |      | 
<no value> | "c:\test.\file.ext" | "c:\test\file.ext" I hadn't thought of this case 
                  until I saw MC ND's answer 

Sie können den Ausdruck in die kanonische äquivalente Form unter Verwendung eines leicht reduzieren FOR-Schleife:

for %%A in ("%~f1.\file.ext") do echo "%%~fA" 

Wie Harry Johnston in seinem Kommentar sagt, funktioniert diese Lösung nicht mit UNC-Root-Pfaden (\\server\shareName) oder langen Pfaden (\\?\c:\somePath). Siehe MC ND's answer, wenn Sie einen dieser Fälle unterstützen müssen. Die Harry Johnston answer ist einfacher, aber es unterstützt nicht den Fall, dass kein Argument gegeben wird.

+1

Sorry, Sie haben vergessen, 'c: .', das wird in 'c: .. \ file' konvertiert. –

+0

Es funktioniert nicht im Stamm einer Freigabe, zB' \\ server \ share. \ file.ext' funktioniert nicht. Ansonsten funktioniert es gut für UNC-Pfade. Es wird auch nicht für lange Pfade funktionieren, d. H. Beginnend mit \\? \ –

+0

@MC ND - Richtig, du bist es! Das ist ein wichtiger Fall. Ich glaube, ich habe das Problem behoben, indem ich den Modifier '~f' hinzugefügt habe. Die Antwort wurde geändert. Vielen Dank! – dbenham

2

Ich sehe keinen Weg, um es für alle Fälle funktionieren zu lassen. Ihre Lösung wird behandeln alle lokalen Pfaden Fälle, aber es UNC oder lange Wege zu handhaben scheint, dass es notwendig ist, zuerst den Pfad zu korrigieren und dann die Datendatei

@echo off 
    setlocal enableextensions disabledelayedexpansion 

    for /f "delims=" %%a in ("%~f1." 
    ) do for /f "delims=" %%b in ("%%~fa\file.ext" 
    ) do echo "%%~fb" 

anhängen Dieses „sollte“ behandeln lokalen, Netzwerk oder lange Pfade (der Grund für die for /f ist die ?), sowohl absolut als auch relativ, und die Möglichkeit, keinen Pfad in der Befehlszeile geben.

+0

+1, Das scheint zu funktionieren, aber es sieht seltsam aus, wenn man bedenkt, dass '\\? \ 'Pfade keine' .' oder '..' relativen Pfadindikatoren unterstützen sollen. Ich mag Harrys einfachere Lösung besser. – dbenham

+0

@dbenham, der Grund für die beiden 'for' Schleifen ist nicht die relativen Pfade (die, wie in Ihrem Code, von'% ~ f1' behandelt werden), sondern um den Fall zu behandeln, wo kein Pfad angegeben ist und der Der letzte Dateiverweis muss auf den aktuellen Ordner verweisen. –

+0

Ahh - am besten. Ich hatte nicht einmal daran gedacht, ohne Argumente zu testen. Es wird nur eine Schleife benötigt, um keinen bereitgestellten Pfad zu unterstützen, aber zwei Schleifen, wie Sie sie haben, sind erforderlich, um sowohl den nicht bereitgestellten Pfad als auch den freigegebenen UNC-Stamm zu unterstützen. Beachten Sie, dass Sie 'EOL =:' hinzufügen sollten, um den unwahrscheinlichen Fall eines relativen Pfades zu behandeln, der mit ';' beginnt. Es gibt keine gültigen Pfade, die mit ':' beginnen. – dbenham

2

Da ~ f mehrere Schrägstriche beseitigt, ich denke, das ist genau so gut wie der ursprüngliche Vorschlag arbeitet, und erscheint auch Aktien Wurzeln und lange Wege richtig zu handhaben:

for /F "delims=" %%i in (%~f1\file.ext) do set filename=%%~fi 
+0

+1, nicht so bequem wie meine Antwort, aber es scheint ein Gewinner zu sein, wenn UNC Freigabe Root oder Long-Pfad-Unterstützung erforderlich ist. Sie sollten jedoch 'EOL =:' hinzufügen, für den unwahrscheinlichen Fall, dass ein Pfad mit einem ';' beginnt. Es gibt keine gültigen Pfade, die mit ':' beginnen, also ist es ein sicheres EOL-Zeichen. – dbenham

+0

Ich habe entschieden, dass ich die Antwort von MC ND besser mag, da sie den Fall eines nicht gelieferten Arguments unterstützt, was das aktuelle Arbeitsverzeichnis bedeutet. – dbenham

+0

Egal, 'EOL =:'. Es wird nicht benötigt wegen '~ f'. (Doh!) – dbenham

Verwandte Themen