2009-09-25 119 views
0

这个蝙蝠码有什么作用?这个批处理文件代码是做什么的?

for /f %%i in ('dir /b Client\Javascript\*_min.js') do (
    set n=%%~ni 
    set t=!n:~0,-4! 
    cp Client\Javascript\%%i build\Client\Javascript\!t!.js 
) 

%%~ni,~n:~0,-4!,%%i,!t!是什么意思?

+0

你能解释一下代码被发现的地方吗? – random 2009-09-25 08:42:59

回答

2

请记住,在批处理文件中,除非您引用了批处理文件的参数,否则您需要转义百分比符号。一旦你删除这些,你会得到

for /f %i in ('dir /b Client\Javascript\*_min.js') do (
     set n=%~ni 
     set t=!n:~0,-4! 
     cp Client\Javascript\%i build\Client\Javascript\!t!.js 
) 

%我是用来放置当前文件已经找到了一个变量的声明。 %〜ni提取%i的文件名部分。 !N:0〜-4!使用延迟扩展从%n%(在上一行中设置)删除最后四个字符!t!只是延迟了上一行中设置的%t%变量的扩展。

延迟扩展被使用,因为否则,一旦遇到该行,变量将被替换,并且将来的迭代不会重新展开该变量。

+0

〜是什么意思? – omg 2009-09-25 09:11:19

+0

我仍然不明白为什么需要延迟扩展。 – omg 2009-09-25 09:15:34

+0

需要延迟扩展来保持向后兼容性。通常,一旦在批处理文件的某行上使用%变量%,它将不会重新读取该变量 - 该行将基本上被替换。延迟扩展可防止每次执行该行时重新读取该变量。由于脚本对for匹配的每一行运行第2-4行,因此这些将被执行多次,如果未使用延迟扩展,则只需复制同一个文件,这显然不是预期的。 – 2009-09-25 19:31:37

1

%~ni只扩展到i的文件名部分。

!n:~0,-4!扩展到除n的最后四个字符以外的所有字符。

通常,命令提示符下的help for将概述for这几天可扩展变量的众多方法。

2
for /f %%i in ('dir /b Client\Javascript\*_min.js') do (

迭代中的每个文件匹配"*_min.js". The用于/ F` DIR command and是完全不必要在这里,虽然只有复杂的事情,尤其是当文件名包含空格,逗号和Client\Javascript文件夹类似。一个更强大和更简单的替代方案将是

for %%i in (Client\Javascript\*_min.js) do (

但这只是旁边的观点。有时人们倾向于写不优雅的批处理文件,而忽略了陷阱和常见错误。这只是一个例子。

 set n=%%~ni 

创建一个可变n,包含文件名(没有任何目录信息或扩展)当前处理的文件的。我们记得for语句迭代它找到的每个文件。随着这条线开始它与这些文件。

 set t=!n:~0,-4! 

创建第二个变量,t,包含一切,但文件名的最后四个字符。这基本上除掉的"_min"

 cp Client\Javascript\%%i build\Client\Javascript\!t!.js 

最后,这份原始文件的目录build\Client\Javascript用新的名字,只是构建。所以像Client\Javascript\foo_min.js这样的文件将被复制到Client\Javascript\foo.js。这里的!t!只是一个延迟评估的环境变量。更多关于下面的内容。这里应该足够了,它只是将该变量的内容插入该行中的该点。

同样,这里不好的做法,将在众多有趣的方式突破:

  1. cp不是Windows的命令使此批将承担cygwin的,安装的GnuWin32或类似的东西。我倾向于避免拥有太多不必要的依赖关系,并坚持Windows提供的内容;在这种情况下是copy命令。我想,两个字节不会在这里杀死任何人。
  2. 任何参数都没有引号。当空格开始出现在文件名中时,会产生有趣的结果。不好,无论如何。

至于为什么使用延迟扩展(的!代替%围绕变量:本for命令包括通过括号分隔这里以及块一切的整个块一次和正常被解析。变量扩展需要当线/命令被解析的地方这将意味着在循环运行之前,留在块中的每个变量将被评估只是以下:

for /f %%i in ('dir /b Client\Javascript\*_min.js') do (
     set n=%%~ni 
     set t= 
     cp Client\Javascript\%%i build\Client\Javascript\.js 
) 

这当然是不是你想在这种情况下。

在像这样的循环中创建和使用变量时,始终需要延迟扩展。不需要延迟扩展一种解决方法是将环内部卸载到一个子程序:

for /f %%i in ('dir /b Client\Javascript\*_min.js') do call :process "%%i" 
goto :eof 
:process 
set n=%~n1 
set t=%n:0,-4% 
copy "Client\Javascript\%~1" "build\Client\Javascript\%t%.js" 
goto :eof 

由于子程序单个“块”(某物以括号分隔)它将由线路被解析线通常。因此,在这里使用正常扩展而不是延迟扩展是安全的。

+0

另一个解决方法是使用“call”命令的一些未公开的功能:“call set t = %% n:〜0,-4 %%” – bk1e 2009-09-25 21:53:45