带括号的块内的所有代码在一个通被解析。在解析时发生使用百分比的正常变量扩展。因此,如果在块中设置变量,则无法使用正常扩展访问该值,因为该值将是您输入块之前存在的值。
您有上述情况。有两种经典的方法来解决这个问题。
1)您可以使用电话和你做了双倍的百分比。 CALL解决了这个问题,因为对于一个被调用的行来说,正常的扩展会发生两次 - 一次是整个块,另一次是在执行该行之前,但在该块中之前的行已经执行之后。第一次扩展将双重百分比转换为单一百分比,第二次扩展实际上扩展了变量。
我不喜欢这个解决方案,因为它很慢,并且还因为CALL导致引用^
字符的问题 - 它们翻倍。
您可以在同一命令上使用多个CALL。每次通话都要求百分比翻倍。所以一个CALL要求2个百分数,两个呼叫需要4个perecents,三个电话8个百分比,等等
2)我认为优选的解决方案是使用延迟扩展。它的速度要快得多,而且你永远不必担心逃跑或当您使用延迟扩展引用特殊字符,如&
,|
,>
,<
等。延迟扩展就像它所说的那样 - 直到线被执行之前变量才被扩展。延迟扩展必须先启用才能使用。在批处理文件中,您可以使用setlocal enableDelayedExpansion
。
可以用延迟扩展会出现一个问题是,如果它们含有!
变量被破坏,当他们被扩展延迟扩充被启用。这通常可以通过在循环中切换延迟扩展和关闭来解决。
如果您在命令提示符下键入HELP SET
,你会得到这个问题的一个很好的描述有一个代码块中扩大变量,以及如何扩展延迟可以提供帮助。描述开始大约半路,用Finally, support for delayed environment variable expansion...
。
注 - 在SET/A计算中使用时不需要展开变量。 SET/A将在执行时自动扩展该值。未定义的变量被视为零。
在你的代码,你可以简单地使用set /a add=add+1
但还有一个更简单的简写方式 - 你可以使用+=
操作:set /a add+=1
。
这是另一种方式,您的代码可以不使用CALL编写。代码没有经过测试,但我认为我是对的。
@echo off
setlocal disableDelayedExpansion
cd "%~dp0"
md newfolder
set add=0
for /f "usebackq eol=: delims=" %%F in ("list.txt") do (
set /a add+=1
set "file=%%F"
setlocal enableDelayedExpansion
set "addx=00!add!"
copy "!file!" "newfolder\!addx:~-3!_!file!"
endlocal
)
pause
我明确地将add
初始化为0,因为它可能已经被设置为一个值。如果您知道它未定义或已设置为0,则不需要初始化。
您的FOR循环处理文件名,并且!
在文件名中有效。这就是我在循环中开启和关闭延迟扩展的原因 - 当我扩展%%F
时,我不希望!
文件名被破坏。文件名也可以从;
开始(尽管极不可能)。如果是这样,那么FOR将跳过该文件,因为默认的EOL字符是;
。一个文件永远不能以:
开头,所以我想将EOL设置为:
。
我把SETLOCAL放在靠近顶部的位置,这样环境变量定义在批处理文件完成后不会持续。
你是天才谢谢 – dskim
我从哪里可以得到关于它的更多信息? ..我是一个初学者。不习惯英语,所以很难理解.. – dskim