2012-11-03 112 views
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 

我做了简单的namechange代码。我通常使用不带'call'的命令,但是在这里它会产生错误信息。这是为什么? ..当我使用%变量%不是%%变量%%,它不工作.. plz告诉我为什么会发生..和最后一个问题..环境变量的值被存储,直到退出cmd。我想知道我怎么可以不设置的..谢谢..批处理命令有什么不同?

回答

1

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

您有上述情况。有两种经典的方法来解决这个问题。

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放在靠近顶部的位置,这样环境变量定义在批处理文件完成后不会持续。

+0

你是天才谢谢 – dskim

+0

我从哪里可以得到关于它的更多信息? ..我是一个初学者。不习惯英语,所以很难理解.. – dskim