Hit*_*kun 1 windows-server-2008 batch-file windows-command-prompt
我正在尝试做一个简单的批处理(这不是全部,但这是使一切都失败的部分)
@echo off
for /f "tokens=*" %%G in ('dir /s /b /a:d "e:\tmp\*"') do (
echo %%G
set fullpath=%%G
set basename=%fullpath:~7%
echo %fullpath%
echo %basename%
)
Run Code Online (Sandbox Code Playgroud)
这个脚本应该从任何地方运行,因此有趣的 for 循环。它应该查看目录,然后做一些事情。
在这个特定的目录中,还有另外 3 个目录:bomslenovodb,cpat和finance
预期输出
e:\tmp\bomslenovodb
e:\tmp\bomslenovodb
bomslenovodb
e:\tmp\cpat
e:\tmp\cpat
cpat
e:\tmp\finance
e:\tmp\finance
finance
Run Code Online (Sandbox Code Playgroud)
实际输出
First run
e:\tmp\bomslenovodb
ECHO is off.
ECHO is off.
e:\tmp\bomslenovodb
e:\tmp\cpat
ECHO is off.
ECHO is off.
e:\tmp\cpat
e:\tmp\finance
Second run
ECHO is off.
ECHO is off.
e:\tmp\finance
e:\tmp\bomslenovodb
e:\tmp\finance
ECHO is off.
e:\tmp\bomslenovodb
e:\tmp\cpat
e:\tmp\finance
Third run
ECHO is off.
e:\tmp\cpat
e:\tmp\finance
e:\tmp\finance
ECHO is off.
e:\tmp\finance
e:\tmp\bomslenovodb
e:\tmp\finance
e:\tmp\finance
Fourth run
e:\tmp\bomslenovodb
e:\tmp\cpat
e:\tmp\finance
e:\tmp\finance
e:\tmp\cpat
e:\tmp\finance
e:\tmp\finance
e:\tmp\finance
e:\tmp\finance
Run Code Online (Sandbox Code Playgroud)
在我看来,它的set fullpath=%%G行为不符合预期,因此它的值设置不正确。
我在 Windows Server 2008 机器上,有什么想法吗?
经典的批处理错误:-)
SET 命令工作正常。是你的扩张失败了。
%VAR%当语句被解析时会发生扩展,并且 FOR 循环中的所有命令都会被一次解析。对于任何带括号的代码块也是如此。因此,在 FOR 循环的整个执行过程中,%fullpath%和的值%basename%是恒定的 - 在进入循环之前存在的值(在这种情况下未定义)。
修复方法是使用延迟扩展,它发生在命令执行之前。延迟扩展必须先启用setlocal enableDelayedExpansion才能使用。并且扩展的语法更改为!VAR!.
@echo off
setlocal enableDelayedExpansion
for /f "tokens=*" %%G in ('dir /s /b /a:d "e:\tmp\*"') do (
echo %%G
set fullpath=%%G
set basename=!fullpath:~7!
echo !fullpath!
echo !basename!
)
Run Code Online (Sandbox Code Playgroud)
但是仍然存在一个潜在的问题。文件名可以包含!字符,并且!当启用延迟扩展时,任何包含的FOR 变量都会在扩展时损坏。解决方案是在循环内打开和关闭延迟扩展。
@echo off
for /f "tokens=*" %%G in ('dir /s /b /a:d "e:\tmp\*"') do (
echo %%G
set fullpath=%%G
setlocal enableDelayedExpansion
set basename=!fullpath:~7!
echo !fullpath!
echo !basename!
endlocal
)
Run Code Online (Sandbox Code Playgroud)
如果您需要保护!文字,并且需要您的变量赋值在迭代中持续存在,那么最简单的方法是使用 CALLed 过程,以便您可以使用正常扩展。只需将 FOR 变量值传输到 CALL 参数即可。但是使用 CALL 比将所有内容直接放入循环中要慢得多。
@echo off
for /f "tokens=*" %%G in ('dir /s /b /a:d "e:\tmp\*"') do call :proc "%%G"
exit /b
:proc
echo %~1
set "fullpath=%~1"
set "basename=%fullpath:~7%"
echo %fullpath%
echo %basename%
exit /b
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
150 次 |
| 最近记录: |