这个批处理文件代码有什么作用?

时间:2009-09-25 08:39:42

标签: windows batch-file

这个蝙蝠代码有什么作用?

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!是什么意思?

4 个答案:

答案 0 :(得分: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
)

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

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

答案 1 :(得分:2)

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

Client\Javascript文件夹中迭代匹配"*_min.js". The dir command and的每个文件/ f`在这里是完全不需要的,但只会使事情变得复杂,特别是当文件名包含空格时,逗号等。

是一种更强大,更简单的替代方案
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. 两个参数都没有引号。当空格开始出现在文件名中时,会导致有趣的结果。也不好。

  3. 至于为什么使用延迟扩展(!而不是%围绕变量: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
    

    由于子程序单个“块”(由括号分隔),它将像往常一样逐行解析。因此,在这里使用正常扩展而不是延迟扩展是安全的。

答案 2 :(得分:1)

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

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

通常,命令提示符下的help for会概述for最近可以扩展变量的多种方式。

答案 3 :(得分:1)

可以找到FOR命令的完整帮助on the Microsoft TechNet site。见here for more information on delayed expansion

// Pseudo code
for each file named *_min.js in the specified directory
    n is set to the file name (*_min)
    t is set to the file name, excluding the last 4 characters (*)
    the file is copied and renamed t.js to the specified directory