Question:
Is it possible to have a function receive a parameter which has both a percent sign and an exclamation mark?
Problem:
I am in a FOR /D
processing directories in this fashion:
FOR /D %%d IN ("%~1\*") DO (
CALL :process "%%~fd"
)
The problem comes when the subdirectory name ( %%~fd
) contains both a %
and a !
(which is completely legal in Windows ), such as C:\\&!x#%
. When I read %1
in the subprocedure :process
, the percent sign disappears. If I EnableDelayedExpansion , then the exclamation mark does.
I read this post and, apparently, this cannot be solved. If delayed expansion is disabled, the %
will be erased. If delayed expansion is enabled, the !
will be.
Example:
ex.bat:
@ECHO OFF
SET arg="%~1"
CALL :clean_echo %arg%
GOTO :EOF
:clean_echo
SET arg="%~1"
SET arg=%arg:&=^&%
SET arg=%arg:|=^|%
SET arg=%arg:<=^<%
SET arg=%arg:>=^>%
ECHO %arg:~1,-1%
GOTO :EOF
If I execute ex.bat "%!"
the output is just !
. The %
is lost when it is passed on to the :clean_echo
subprocedure.
@ECHO OFF
SETLOCAL
FOR /d %%a IN (*) DO (ECHO %%~fa
SET "var=%%~fa"
CALL :proc var
)
GOTO :EOF
:proc
FOR /f "tokens=1*delims==" %%x IN ('set %1 2^>nul') DO IF /i "%1"=="%%x" (
ECHO %%y
)
GOTO :eof
You don't say enough about your application, but essentially passing such strings as a parameter is doomed to fail. Here's a method that may work for you, although it won't cope with the data starting with =
(I've seen filenames containing =
.)
It's a game of piggy-in-the-middle with the parser being piggy. So long as your data remains assigned to a metavariable it seems fine. Really depends on the unstated - precisely what you want to do with it.
It could be done, you need to double the percents and prefix the exclamation marks with a caret.
But then it fails with single carets in the name and that can't be solved in a proper way.
As Magoo said, it's always better to use a variable and only transfer the variable name instead of the content.
But in the function you should use delayed expansion to expand the variable.
setlocal DisableDelayedExpansion
FOR /D %%d IN ("%~1\*") DO (
set "var=%%~fd"
setlocal EnableDelayedExpansion
CALL :process var
endlocal
)
exit /b
:process
set "content=!%1!"
echo !content!
exit /B
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.