2009-04-22 12 views
18

Vorrei ottenere la directory principale di un file all'interno di un file .bat. Quindi, data una variabile impostata su "C:\MyDir\MyFile.txt", mi piacerebbe ottenere "C:\MyDir". In altre parole, l'equivalente della funzionalità dirname() in un tipico ambiente UNIX. È possibile?Come ottengo l'equivalente di dirname() in un file batch?

+1

Ho aggiunto un commento sui nomi di file con spazi; ho dimenticato di testare con quelli. – Joey

risposta

20
for %%F in (%filename%) do set dirname=%%~dpF 

Questo imposterà %dirname% per l'unità e la directory del nome del file memorizzato in %filename%.

Attenzione con nomi di file contenenti spazi, però. O devono essere impostati con le virgolette che circondano:

set filename="C:\MyDir\MyFile with space.txt" 

o si deve mettere le virgolette attorno al argomento nella for ciclo:

for %%F in ("%filename%") do set dirname=%%~dpF 

Entrambi i metodi funzionerà, sia allo stesso tempo ha vinto 't :-)

+0

Penso che tu intenda, "metti le * virgolette * attorno all'argomento nel ciclo for:" – aphoria

+0

Sì, grazie. Attualmente non riesco a pensare correttamente :) – Joey

+0

@mosh, qual è il risultato atteso per un hardlink? Si noti inoltre che i workaround sono sensibili ai nomi di file Unicode e al carattere della console. – Joey

6

Se per qualsiasi motivo non è possibile utilizzare per la (senza le estensioni ai comandi ecc) potrebbe essere in grado di farla franca con il .. \ mod:

set file=c:\dir\file.txt 
set dir=%file%\..\ 
+0

Questa soluzione (file cd/d \ ..) funziona meglio con win7, l'altra soluzione a volte fallisce con win7 %% ~ dpF. – mosh

+0

Vedere il mio commento alla risposta @ ben-chiave. – Vertigo

3

Il problema con il ciclo for è che lascia il trailing \ alla fine della stringa. Ciò causa problemi se si desidera ottenere il dirname più volte. Forse è necessario ottenere il nome della directory che è il nonno della directory contenente il file anziché solo la directory genitore. Semplicemente usando la tecnica for loop una seconda volta si rimuoverà \, e non si otterrà la directory dei nonni.

Questo non si può semplicemente fare quanto segue.

set filename=c:\1\2\3\t.txt 
for %%F in ("%filename%") do set dirname=%%~dpF 
for %%F in ("%dirname%") do set dirname=%%~dpF 

questo imposterà nomedir a "c: \ 1 \ 2 \ 3", non "c: \ 1 \ 2".

La seguente funzione risolve il problema rimuovendo anche il trailing \.

:dirname file varName 
    setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION 
    SET _dir=%~dp1 
    SET _dir=%_dir:~0,-1% 
    endlocal & set %2=%_dir% 
GOTO :EOF 

Si chiama come segue.

set filename=c:\1\2\3\t.txt 
call :dirname "%filename%" _dirname 
call :dirname "%_dirname%" _dirname 
+0

Buona soluzione per il problema finale. Altrimenti non si può usare direttamente il comando ""% dirname% "' dato che la citazione finale sarebbe stata sfuggita dalla barra precedente. In tal caso il '"% dirname% \ "' funziona. Ma solo uno di loro alla volta. – Vertigo