2009-04-22 9 views
18

.batファイル内のファイルの親ディレクトリを取得したいとします。だから、変数が"C:\MyDir\MyFile.txt"に設定されていれば、"C:\MyDir"を取得したいと思います。つまり、典型的なUNIX環境ではdirname()の機能に相当します。これは可能ですか?バッチファイルでdirname()に相当するものを取得するにはどうすればよいですか?

+1

スペースでファイル名についての発言を追加しました。それらと一緒にテストするのを忘れてしまった。 – Joey

答えて

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

これは%filename%に保存されたファイル名のドライブおよびディレクトリへ%dirname%を設定します。

スペースを含むファイル名には注意してください。どちらの

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

方法は、両方の同じ時間ウォンで、動作します:

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

か、forループで引数の前後に引用符を置く必要があります:彼らは周囲の引用符を使用して設定する必要がありますどちらか

+0

私はあなたが "forループの引数の周りに*引用符*を置くことを意味すると思います:" – aphoria

+0

よろしくお願い致します。現在適切に考えることができません:) – Joey

+0

@mosh、ハードリンクの予想される結果は?また、回避策はUnicodeファイル名とコンソールフォントに敏感です。 – Joey

6

:-)」トンは何でもあなたが(なしコマンド拡張機能など)に使用することはできません理由であなたが逃げることができるかもしれない場合は.. \ハック:

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

このソリューション(cd/dファイル\ ..)はwin7でうまく動作しますが、他の解決策はwin7 %%〜dpFで失敗することがあります。 – mosh

+0

@ ben-key answerへの私のコメントを参照してください。 – Vertigo

3

forループの問題は、文字列の最後に\が残ることです。 dirnameを複数回取得する場合は、この問題が発生します。おそらく、親ディレクトリの代わりにファイルを含むディレクトリの祖父母であるディレクトリの名前を取得する必要があります。単純にforループ技法を使用すると、\が削除され、祖父母ディレクトリは取得されません。

これは、単に次のことを行うことはできません。

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

これは、 "C:\ 1 \ 2 \ 3" にDIRNAMEを設定しますない "C:\ 1 \ 2"、。

次の関数は、後続の\も削除することでこの問題を解決します。

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

以下のように呼ばれます。

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

末尾の\問題には良い解決策です。さもなければ、最後の引用符が前のスラッシュでエスケープされるので、 ''%dirname% "'を直接使用することはできません。そのような場合、 ''%dirname%\ "'が動作します。しかし、一度にどちらか一方だけ。 – Vertigo

関連する問題