9

The following mostly works. 'Mostly', because the use of the SOMETHING..\tasks\ pathname confuses Spring when a context XML file tries to include another by relative pathname. So, what I seem to need is a way, in a BAT file, of setting a variable to the parent directory of a pathname.

set ROOT=%~dp0
java -Xmx1g -jar %ROOT%\..\lib\ajar.jar %ROOT%\..\tasks\fas-model.xml tasks
bmargulies
  • 97,814
  • 39
  • 186
  • 310

3 Answers3

18

To resolve a relative path name you can utilize a sub routine call. At the end of your batch file place the following lines:

GOTO :EOF

:RESOLVE
SET %2=%~f1 
GOTO :EOF

This is a sub routine that resolves its first parameter to a full path (%~f1) and stores the result to the (global) variable named by the 2nd parameter

You can use the routine like this:

CALL :RESOLVE "%ROOT%\.." PARENT_ROOT

After the call you can use the variable %PARENT_ROOT% that contains the parent path name contained in the %ROOT% variable.

Your complete batch file should look like this:

SET ROOT=%~dp0

CALL :RESOLVE "%ROOT%\.." PARENT_ROOT

java -Xmx1g -jar "%PARENT_ROOT%\lib\ajar.jar" "%PARENT_ROOT%\tasks\fas-model.xml" tasks

GOTO :EOF

:RESOLVE
SET %2=%~f1 
GOTO :EOF
Frank Bollack
  • 24,478
  • 5
  • 49
  • 58
  • Hm, nice idea. I'd have abused `pushd`, `popd` and `%CD%` but this one is more elegant, actually. – Joey Jan 31 '10 at 16:31
  • @Johannes: Thanks, I also thought about `pushd` and `popd`, but i didn't remember the `%CD%` variable any more. So this way was more obvious to me. – Frank Bollack Jan 31 '10 at 16:39
  • Paraphrasing Perl: *»Batch files: There's more than one way to do it«* ;-) – Joey Jan 31 '10 at 16:52
8

Here is a one liner

for %%A in ("%~dp0\..") do set "root_parent=%%~fA"
dbenham
  • 127,446
  • 28
  • 251
  • 390
3

To expand on the accepted answer, if you want to keep marching up the path (to get the parent's parent directory, for example), strip the trailing slash:

:PARENT_PATH
:: use temp variable to hold the path, so we can substring
SET PARENT_PATH=%~dp1
:: strip the trailing slash, so we can call it again to get its parent
SET %2=%PARENT_PATH:~0,-1%
GOTO :EOF

Usage:

CALL :PARENT_PATH "%~dp0" PARENT_ROOT
CALL :PARENT_PATH "%PARENT_ROOT%" PARENT_ROOT
echo Parent Root is: %PARENT_ROOT%

would yield C:\My\Path from C:\My\Path\Child\file.bat.

If I understood it better, I'd suggest a "wrapper function" so you could CALL :REMOVE_SEGMENTS %path% 3 PARENT to strip the last 3 segments from %path%.

Community
  • 1
  • 1
drzaus
  • 24,171
  • 16
  • 142
  • 201