lxvs
lxvs

Reputation: 1030

How to Let Percent Symbols (%) Read From a File Get Expanded in Windows Batch File?

This is file path.txt:

%APPDATA%\foo

This is a part of batch file read-path.bat:

...
for /f %%i in (path.txt) do if not defined fooDir (
    if exist %%i (
        set "fooDir=%%i"
    ) else (
        >&2 echo ERROR: Invalid definition of fooDir: %%i
        pause
        popd
        exit /b 1
    )
)
...

When I run this batch file, it prompts that

ERROR: Invalid definition of fooDir: %APPDATA%\foo

How can I let it get parsed to C:\Users\user\AppData\Roaming\foo, instead of %APPDATA%\foo?

Upvotes: 1

Views: 274

Answers (1)

Mofi
Mofi

Reputation: 49097

The following code could be used:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "usebackq eol=| delims=" %%i in ("%~dp0path.txt") do if not defined fooDir (
    set "FolderPath=%%~i"
    setlocal EnableDelayedExpansion
    call set "FolderPath=!FolderPath!"
    for %%j in ("!FolderPath!\") do (
        endlocal
        if exist "%%~fj" (
            set "fooDir=%%~fj"
        ) else (
            endlocal
            >&2 echo ERROR: Invalid definition of fooDir: %%j
            pause
            exit /B 1
        )
    )
)
set foodir
endlocal

That code works for following folder paths in path.txt in directory of the batch file:

%APPDATA%\foo
%APPDATA%\Development & Test()!
%APPDATA%\..\Roaming\Development & Test()!\\\

But it does not work for:

%APPDATA%\Development % Test()!

So if the folder path contains additionally to zero or more environment variable references also a percent sign which should be interpreted literally as being part of a folder name, the code does not work.

The command CALL left to set "FolderPath=!FolderPath!" results in interpreting the percent signs in folder path read from the file and expanding the environment variable references, but also in removing a single percent sign which should be interpreted as literal character and not as start/end of an environment variable reference. There should not found by cmd.exe a file with name set in current directory or a directory listed in environment variable PATH having a file extension listed in environment variable PATHEXT as in this case this executable or script would be called instead of executing internal command SET.

The inner FOR is used to get the real absolute folder path always ending with a single backslash on folder path read from file contains relative path parts as well according to the Microsoft documentation about Naming Files, Paths, and Namespaces.

Note: The environment variable foodir is defined always with a backslash at end.

To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.

  • call /?
  • echo /?
  • endlocal /?
  • exit /?
  • if /?
  • pause /?
  • set /?
  • setlocal /?

Upvotes: 1

Related Questions