命令行批处理脚本,FOR循环内的变量的SET不起作用

时间:2019-07-09 15:55:49

标签: batch-file cmd

我正在尝试使用以下代码将目录(_sourceFolder)(包括子目录)的总大小归为一个变量(_localvar)。

我尝试启用setlocal enabledelayedexpansion,但没有帮助。

@echo off
set _sourceFolder="D:\data"
dir/A-D /S %_sourceFolder%|for /F "tokens=*" %%a in ('FIND "bytes"') do set _localvar=%%a
echo %_localvar%

但是没有执行子命令set _localvar=%%a,相反,我在stdout中看到了一些输出,例如:

    C:\>set _localvar=1 File(s)         27.686 bytes
    C:\>set _localvar=1 File(s)         27.686 bytes
    C:\>set _localvar=3272 File(s)  1.812.083.061 bytes
    C:\>set _localvar=1 File(s)         27.686 bytes
    C:\>set _localvar=3275 File(s)  1.812.166.119 bytes
    C:\>set _localvar=0 Dir(s)   7.431.806.976 bytes free

但是%_localvar%仍然为空/未设置。我期望%_localvar%上的输出显示已填充/设置了stdout

有人看到我在这里犯的错误吗?

2 个答案:

答案 0 :(得分:3)

pipe (|)会为双方启动两个新的cmd实例,因此不会将任何环境更改(如变量)转移到托管cmd实例中。

dir命令行移动到for /F的集合中,如下所示:

for /F "tokens=*" %%a in ('dir /A-D /S "%_sourceFolder%" ^| find "bytes" ^| find /V "free"') do set _localvar=%%a

请注意,在此处对管道进行了转义(如^|),以便将其从托管cmd实例中隐藏,因此它在由{创建的cmd实例中执行{1}}。尽管变量分配不再包含在管道中,所以分配的值最终将变为可用。

我添加了另一个过滤器(for /F,因为我假设您不想捕获最后的“无字节”行,而是之前的那一行。

答案 1 :(得分:0)

如果您要查找的是所有文件大小的总和,那么这会更简单一些。它不依赖于解析DIR命令文本的输出。

FOR /F %%a IN ('powershell -NoLogo -NoProfile -Command ^
    "(Get-ChildItem -File -Recurse |" ^
        "Measure-Object -Sum -Property Length).Sum"') DO (SET "_localvar=%%a")
ECHO %_localvar%