我正在尝试从批处理文件中调用命令,该文件从文件中读取行
这是正常的,除了行包含重定向字符>
。
有没有办法告诉call
转义此字符,还是在for循环的内容中替换它?
我查看了setlocal enabledelayedexpansion
和(当通话更新为使用!
时,它仍然无效。)
set /p status=<%tmp_file%
for /f "delims=*" %%a in (%tmp_file%) do (
echo "%%a"
call check.bat "%%a"
echo.
if not "%errorlevel%" == "0" do exit /b 1
)
这会产生以下输出(当check.bat
echo的%1
)
"a"
"a"
"b -> b"
"b -"
我试图在>
内替换%%a
但我不完全确定如何实现这一点,每次尝试时都会产生一个空字符串,即
set line=%a:^>=¬%
编辑1
更一些说明(似乎只有在%1
设置为变量,然后使用该变量的情况下才会出现这种情况)?:
check.bat
:
set rawinput=%1
set input=%~1
echo %1
echo "%rawinput%"
echo "%input%"
echo.
这会产生以下输出,虽然我不太清楚为什么将%1
设置为变量会导致它变形值?
"a"
"a"
""a""
"a"
"b -> b"
"b -> b"
"b -"
有趣的是b -> b
仅输出2次,echo "%rawinput%"
根本没有显示。
echo "%input%"
和echo "%rawinput%"
都写入名为b
的文件。
这意味着check.bat
的{{1}}必须解释为:
b -> b
如果有人能够了解为什么批处理文件中的 echo "b -> b"
echo ""b -> b""
echo "b -> b" REM - this is what 'should' be happening, however does appear to be the case, as it writes '' to a file named b
echo.
似乎没有表现出来,我们将不胜感激。
答案 0 :(得分:3)
不要试图使用call by value
,批次几乎不可能
只需使用值设置一个新变量,然后使用变量名称。
for /f "delims=" %%a in (%tmp_file%) do (
set "line=%%a"
call :check
)
exit /b
:check
setlocal EnableDelayedExpansion
echo(!line!
endlocal
exit /b
编辑:您的问题
您尝试使用
使用内容"b -> b"
调用函数
call check.bat "%%a"
这将扩展为
call check.bat ""b -> b""
这就是问题!
由于>
重定向字符现在位于引号之外,它会将check.bat的输出重定向到文件b
。
使用调用时,您可以转义特殊字符(在引号之外),但这有点高级并且存在许多问题。
所以,我会再次推荐,不要直接使用通话中的内容 您可以使用引用,例如
for /f "delims=" %%a in (%tmp_file%) do (
set "line=%%a"
call :check line
)
check.bat
setlocal EnableDelayedExpansion
set "var=!%1!"
echo(!var!
答案 1 :(得分:2)
您修改后的check.bat
中存在多个问题引号是一个状态机,因为第一个引用引用语义ON,第二个OFF,第三个ON等。未引用(和未转义)>
被解释为重定向输出的指令。 / p>
我通过输入一堆ECHO语句来大量修改check.bat,以提供正在发生的事情的叙述。您的原始代码作为所有CAPS嵌入我的版本中。
以下是我修改版本的输出,我希望能解释为什么你会得到你的结果。在您尝试了解我的修改后的check.bat如何生成此输出之前,我希望您阅读此输出。
"a"
---------------------------------------------
Executing: SET RAWINPUT=%1 which expands to SET RAWINPUT="a"
Here is the result:
rawinput="a"
Executing: SET INPUT=%~1 which expands to SET INPUT=a
Here is the result:
input=a
Executing: ECHO %1 which expands to ECHO "a"
"a"
Executing: ECHO "%RAWINIPUT%" which expands to ECHO ""a""
""a""
Executing: ECHO "%INPUT%" which expands to ECHO "a"
"a"
"b -> b"
---------------------------------------------
Executing: SET RAWINPUT=%1 which expands to SET RAWINPUT="b -> b"
Here is the result:
rawinput="b -> b"
Executing: SET INPUT=%~1 which expands to SET INPUT=b -> b
Here is the result:
input=b -
Also created a file named "b" because the output of the command
is redirected. The file is empty because SET has no output.
Volume in drive C is OS
Volume Serial Number is EE2C-5A11
Directory of C:\Users\Public\utils
11/20/2012 09:30 AM 0 b
1 File(s) 0 bytes
0 Dir(s) 316,104,765,440 bytes free
Executing: ECHO %1 which expands to ECHO "b -> b"
"b -> b"
Executing: ECHO "%RAWINIPUT%" which expands to ECHO ""b -> b""
There is no screen output because output was redirected to file "b"
Here are the contents of "b":
""b -
Executing: ECHO "%INPUT%" which expands to ECHO "b -"
"b -"
这是我修改后的check.bat,它产生上面的输出。
setlocal enableDelayedExpansion
set value=%1
set "unquotedValue=%~1"
echo ---------------------------------------------
echo Executing: SET RAWINPUT=%%1 which expands to SET RAWINPUT=!value!
SET RAWINPUT=%1
echo Here is the result:
set rawinput
echo.
echo Executing: SET INPUT=%%~1 which expands to SET INPUT=!unquotedValue!
SET INPUT=%~1
echo Here is the result:
set input
if exist b (
echo.
echo Also created a file named "b" because the output of the command
echo is redirected. The file is empty because SET has no output.
echo.
dir b
del b
)
echo.
echo Executing: ECHO %%1 which expands to ECHO !value!
ECHO %1
echo.
echo Executing: ECHO "%%RAWINIPUT%%" which expands to ECHO "!rawinput!"
ECHO "%RAWINPUT%"
if exist b (
echo.
echo There is no screen output because output was redirected to file "b"
echo Here are the contents of "b":
type b
del b
)
echo.
echo Executing: ECHO "%%INPUT%%" which expands to ECHO "!input!"
ECHO "%INPUT%"
echo.
如果你没有在check.bat中添加任何引号,你可以通过变量获得所需的结果
set rawinput=%1
echo %rawinput%
但如果您的原始文本文件包含自己的引号,那么一切都会崩溃。
这就是为什么jeb建议将每一行存储在主例程中的变量中,然后将变量的名称传递给check.bat。在check.bat中,您可以使用延迟扩展来安全地处理任何值,而不必担心引号或转义。