arathorn
arathorn

Reputation: 2138

How do I get the equivalent of dirname() in a batch file?

I'd like to get the parent directory of a file from within a .bat file. So, given a variable set to "C:\MyDir\MyFile.txt", I'd like to get "C:\MyDir". In other words, the equivalent of dirname() functionality in a typical UNIX environment. Is this possible?

Upvotes: 34

Views: 41202

Answers (4)

Dmitry Sokolov
Dmitry Sokolov

Reputation: 3180

To get rid of the trailing \ just pass the result %~dpA+. into the next for and get the full path %~fB:

C:\> @for /f "delims=" %A in ("c:\1\2\3\t.txt") do @for /f "delims=" %B in ("%~dpA.") do @echo %~fB
c:\1\2\3

C:\> @for /f "delims=" %A in ("c:\1\2\3\t 1.txt") do @for /f "delims=" %B in ("%~dpA.") do @echo %~fB
c:\1\2\3

C:\> @for /f "delims=" %A in ("c:\1\2\3 3\t 1.txt") do @for /f "delims=" %B in ("%~dpA.") do @echo %~fB
c:\1\2\3 3

Upvotes: 0

Benilda Key
Benilda Key

Reputation: 3094

The problem with the for loop is that it leaves the trailing \ at the end of the string. This causes problems if you want to get the dirname multiple times. Perhaps you need to get the name of the directory that is the grandparent of the directory containing the file instead of just the parent directory. Simply using the for loop technique a second time will remove the \, and will not get the grandparent directory.

That is you cannot simply do the following.

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

This will set dirname to "c:\1\2\3", not "c:\1\2".

The following function solves that problem by also removing the trailing \.

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

It is called as follows.

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

Upvotes: 7

Anders
Anders

Reputation: 101569

If for whatever reason you can't use FOR (no Command Extensions etc) you might be able to get away with the ..\ hack:

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

Upvotes: 11

Joey
Joey

Reputation: 354356

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

This will set %dirname% to the drive and directory of the file name stored in %filename%.

Careful with filenames containing spaces, though. Either they have to be set with surrounding quotes:

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

or you have to put the quotes around the argument in the for loop:

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

Either method will work, both at the same time won't :-)

Upvotes: 29

Related Questions