批处理命令有什么区别?

时间:2012-11-03 18:10:01

标签: batch-file dos

@echo off
cd %~dp0
md .\newfolder
for /f "usebackq delims=" %%f in ("list.txt") do (
  call set /a add=%%add%%+1
  call set addx=0000%%add%%
  call set addx=%%addx:~-3%%
  call copy "%%f" ".\newfolder\%%addx%%_%%f"
)
pause

我制作了简单的名称更改代码。我通常使用没有“呼叫”的命令。但在这里它会产生错误信息。这是为什么? ..当我使用%variable%而不是%% variable %%时,它不能正常工作.. 请告诉我为什么会发生..并且最后一个问题..环境变量的值存储到退出cmd。我想知道我怎么能解决这个问题..谢谢..

1 个答案:

答案 0 :(得分:1)

括号内的所有代码都在一次通过中解析。使用百分比的正常变量扩展发生在分析时。因此,如果在块中设置变量,则无法使用常规扩展访问该值,因为该值将是您在输入块之前存在的值。

你有上述情况。有两种经典的方法可以解决这个问题。

1)您可以使用CALL并将百分比加倍。 CALL解决了这个问题,因为正常扩展对于一个被调用的行发生了两次 - 一次是针对整个块,一次是在执行该行之前,但是在块中的前一行执行之后。第一次扩展将双倍百分比转换为单一百分比,第二次扩展实际上扩展了变量。

我不喜欢这个解决方案,因为它很慢,而且因为CALL导致引用^字符的问题 - 它们加倍了。

您可以在同一命令上使用多个CALL。每次调用都需要将百分比加倍。所以一个CALL需要2%,两个CALL需要4个perecents,3个CALL需要8%等等。

2)我认为首选解决方案是使用延迟扩展。它的速度要快得多,而且当您使用延迟扩展时,您也不必担心转义或引用&|><等特殊字符。延迟扩展正如它所说的那样 - 变量直到行执行之前才会扩展。必须先启用延迟扩展才能使用。在批处理文件中,您可以使用setlocal enableDelayedExpansion

延迟扩展可能出现的一个问题是FOR变量如果包含!则会损坏,并且在展开时启用延迟扩展。这通常可以通过在循环内切换延迟扩展来解决。


如果从命令提示符处键入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放在顶部附近,以便在批处理文件完成后环境变量定义不会保留。