用于处理FOR LOOP中的随机%字符的批处理文件

时间:2013-08-18 23:19:44

标签: batch-file cmd

我正在尝试将文件名作为FOR循环参数传递给单独的批处理文件。问题是,如果文件名包含特殊字符(尤其是%),则参数不会转到被调用的脚本。 EG -

FIRST_SCRIPT.bat如下 -

cd "C:\theFolder"
for /R %%a in (*.*) do call SECOND_SCRIPT "%%~a"

SECOND_SCRIPT.bat如下 -

ECHO %1

如果文件名包含%eg。 “%STATS.txt”,输出最终为

of STATS.txt

哪个错了。我尝试过使用Setlocal DisableDelayedExpansion,但收效甚微

Setlocal DisableDelayedExpansion
for /R %%a in (*.*) do (
SET "var=%%~a" 
Setlocal EnableDelayedExpansion
call TEST_UPGRADE "%var%" "%%~a"
)

还有其他stackoverflow答案,但它们都需要事先知道%字符。由于文件名不在我们的控制范围内,因此这些解决方案对我们无效。有没有办法解决这个问题?

谢谢!

platform:适用于Windows XP的cmd.exe

3 个答案:

答案 0 :(得分:6)

Aacini显示的解决方案适用于%以及!,但它会因插入符^失败。

但解决方案很简单。

首先,必须禁用延迟扩展以处理感叹号 文件名现在正好在var变量中 插入符号和百分比的问题是由CALL引起的。 这可以通过CALL使用CALL仅使用%%var%%的第二个百分比扩展阶段来解决。

Setlocal DisableDelayedExpansion
for /R %%a in (*.*) do (
  SET "var=%%~a" 
  call TEST_UPGRADE "%%var%%"
)

下一个问题是在second.bat中显示文件名。 这应该通过启用延迟扩展来完成,以避免特殊字符出现问题,或者您需要始终引用。

set "var=%~1"
setlocal EnableDelayedExpansion
echo Filename: !var!

答案 1 :(得分:4)

带有临时文件的解决方案:

first.bat

@ECHO OFF &SETLOCAL
REM to escape the '%' use a second '%'
SET "var=40%% &off!.txt"
REM get a random temp file name
:loop
SET "tname=%temp%%random%%random%"
IF EXIST "%tname%" GOTO :loop
SETLOCAL ENABLEDELAYEDEXPANSION
REM save the variable in the file
>"%tname%" (ECHO(!var!)
CALL "second.bat" "%tname%"
ENDLOCAL

second.bat

@ECHO OFF &SETLOCAL
SET "tname=%~1"
<"%tname%" set/p"var="
SETLOCAL ENABLEDELAYEDEXPANSION
ECHO !var!
DEL "%tname%" /F /Q

..输出是:

40% &off!.txt

答案 2 :(得分:3)

编辑:我添加了启用/禁用延迟扩展技术,以避免感叹号出现问题。

@echo off
setlocal DisableDelayedExpansion
for /F "delims=" %%a in ('dir /B *.txt') do echo %%a
echo/

for %%a in (*.txt) do (
SET "var=%%a" 
setlocal EnableDelayedExpansion
call :TEST_UPGRADE "!var:%%=%%%%!" "%%~a"
endlocal
)
goto :EOF

:TEST_UPGRADE
ECHO First: %1  Second: %2
exit /B

输出示例:

% of STATS.txt
Discount of 10% in all.txt
Normal file.txt

First: "% of STATS.txt"  Second: " of STATS.txt"
First: "Discount of 10% in all.txt"  Second: "Discount of 10 in all.txt"
First: "Normal file.txt"  Second: "Normal file.txt"