3

Within my batch file I have a variable that contains a file path:

SET VAR1=C:\Folder1\Folder2\File.txt

I would like to extract on the directory structure and retreive:

C:\Folder1\Folder2\

I have read threads like this where I need to use %~dp0 where 0 I believe is passed as a parameter. I have tried %~dpVAR1 but that doesn't work. How can I get the output I'm looking for, but with a variable containing the file path?

Also, to make matters difficult, I have to perform all of this within an IF condition which means that once the variable is declared, I will need to refer to it with ! instead of % (I have declared setlocal enableextensions enabledelayedexpansion at the beginning of my script to allow for this).

Any help is much appreciated!

Thanks!

Andrew

4 Answers 4

10

You are attempting to use parameter expansion syntax on an environment variable - that cannot work. But it is relatively easy to do what you want.

Using a CALL (relatively slow):

(...
  call :getPath "!var!" var
  ...
)
exit /b

:getPath
set "%2=%~dp1"
exit /b

Using FOR, assuming the variable does not contain any wildcards (fast)

(...
  for %%F in ("!var!") do set "var=%%~dpF"
 ...
)

Using FOR, if the variable may contain wildcards (also fast)

(...
  for /f "delims=" %%F in ("!var!") do set "var=%%~dpF"
 ...
)

Note 1: If the variable does not contain the full path, then all the solutions will attempt to resolve the name into an absolute path and will return the full absolute path. For example, if var contains foobar\test.txt, then the solutions will include the full path to the current directory, even if the file is not found. Something like c:\pathToCurrentDirectory\foobar\.

Note 2: All solutions above will remove all quotes from the path.

Note 3: A path could include the ! character, which will cause problems when expanding %~dp1 or %%~dpF because you have delayed expansion enabled. The delayed expansion will corrupt both ^ and ! if the value contains !. There is a solution that involves protecting both ! and ^. Here is a demonstration applied to the last solution above. The protection requires normal expansion, and since you are within a code block, it requires at least one CALL. It could be done without a subroutine, but it is easier with a subroutine. The subroutine assumes the variable is named var.

(...
  call :getPath
 ...
)
exit /b

:getPath
set "var=!var:"=!"
set "var=!var:^=^^^^!"
set "var=%var:!=^^^!%" !
for /f "delims=" %%F in ("!var!") do set "var=%%~dpF" !
exit /b
Sign up to request clarification or add additional context in comments.

2 Comments

Any idea why your second example worked for me only after removing the quotes and exclamation points?
@fordareh - ??? The question is explicitly trying to extract path information from the content of a variable. It cannot work without the exclamation points. You must be doing something that is not directly related to the question.
1

I do believe (once again) many questions are on the same topic (string constraints, or splitting strings).

Instead of giving you the whole code, I'm going to give you a template and explain why %~dpVAR! didn't work.

Firstly, why %~dpVAR! did't work.

Before I get into modifiers, let's discuss parameters. You may know that batch files can parse parameters to each other. These parameters can be called by using a single percent sign (%) in front of the numbers 0-9. As far as I'm aware (someone might have made a way for more to be parsed), only 9 parameters can be parsed. You may think that is wrong (there's 10 parameters right?). Parameters 1-9 are parsed to the batch file (or function within one), %0 is the file path of the batch file (or function name). If you look, %~dp0 shares some (not really) resemblance to %0. This will be discussed below.

Secondly, the term %~dp0 has modifiers in it. Modifiers are things that modify variables (only in the case of parameters and those declared in for loops, you know the ones with double percent signs like %%i) and parameters. The modifier d expands the parameter to a drive letter only while p expands the parameter to a path only. You may think that these would contradict themselves, but parameters can be combined to create extremely wacky formats.

So, as you can see, you attempt at replacing 0 with your variable name failed because it's not specified for those sort of things.

Now, on to the template.

You can constrain variables (and put them into other variables) like this: set variable=!variable:~offset,amount!

Don't worry if that seems confusing, I'm about to explain the components.

Firstly, notice that there is no /a switch. This is because this is not a mathematical function (don't really know why I added this). So, before I explain it, here's an example of what it would do to a variable name numbers that has the value of 0123456789.

set numbers=!numbers:~5,1!

By using that line of code, numbers would now equal 5. This is because it is recreating the variable with a smaller version of the original value (gee this is hard to explain). As you can see, there is a 5 where offset was on the template above. This is because it is skipping the first 5 characters and setting the variable as the next amount, or 1 character (I really hope you're getting this).

So basically, it sets a variable as a shorter value of a different (or the same) variable determined by the offset and the amount of characters to contain in it.

I really hope this helps because I probably wouldn't understand a word of this.

Can someone redirect this poor guy to a link explaining this better (I tried, ok!)?

1 Comment

Your explanation for why the OP's code doesn't work is fine, though a bit wordy. The remainder dealing with substring operation is not relevant to the problem at hand.
0

Complete example of extracting paths from variable:

@echo off
set /p Fullpath="Specify full path: "
call :getPath %Fullpath% filename folder
echo %filename%
echo %folder%
pause
exit /b

:getPath
set "%2=%~nx1"
set "%3=%~dp1"
exit /b

Comments

-2

Would this work:

SET VAR1=C:\Folder1\Folder2\File.txt
echo %var1%

Where Echo is the name of your exe.

%CD% may work as well: Echo %CD%

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.