0
@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 。我想知道如何取消它..谢谢..

4

1 回答 1

1

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

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

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

我不喜欢这个解决方案,因为它很慢,还因为 CALL 会导致引用^字符出现问题 - 它们加倍。

您可以在同一命令上使用多个 CALL。每次通话都要求百分比翻倍。所以一个 CALL 需要 2%,两个 CALL 需要 4%,三个 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 放在顶部附近,以便在批处理文件完成后环境变量定义不会持续存在。

于 2012-11-03T23:07:55.413 回答