Vit*_*ala 0 windows batch-file
如何计算文件夹和子文件夹文件中的文件。文件夹名称和文件数以及子文件夹名称和文件数。前任:
test1 : 2
test1\test11 :3
newfolder : 5
newfolder : 10
Run Code Online (Sandbox Code Playgroud)
像这样。
robocopy "x:\target\folder" "x:\target\folder" /l /nocopy /is /e /nfl /njh /njs
Run Code Online (Sandbox Code Playgroud)
或者
pushd "x:\target\folder" && (
robocopy . . /l /nocopy /is /e /nfl /njh /njs
popd
)
Run Code Online (Sandbox Code Playgroud)
这将简单地调用robocopy,但我们不会复制任何内容,而是要求不复制任何内容,只返回应处理内容的列表 ( /nocopy /l)。我们要求从当前文件夹(先前的复制pushd命令时)到当前文件夹,包括在处理相同的文件(/is),处理空的子文件夹(/e,以包括与0的文件夹),但仅处理两个电平(/lev:2当前文件夹和下面的一个),不生成文件列表 ( /nfl),没有作业标题 ( /njh) 和没有作业摘要 ( /njs)
结果将是相同的列表,但具有文件夹名称和更改列中的文件数
保持原始输出格式
@echo off
setlocal enableextensions disabledelayedexpansion
pushd "x:\target\folder" && (
for /f "tokens=1,*" %%a in ('
robocopy . . /l /nocopy /is /e /nfl /njh /njs
') do echo %%~fb : %%a
popd
)
Run Code Online (Sandbox Code Playgroud)
这将使用 afor /f处理前一个robocopy命令,将行拆分为两个标记,第一个将包含文件数并存储在 中%%a,第二个包含行的其余部分并将存储在%%b. 对于内部robocopy命令输出中的每一行,do执行子句中的代码:只需 echo 以相反的顺序控制台两个标记。
如果robocopy不能使用(比 Vista 旧的操作系统),则
@echo off
setlocal enableextensions disabledelayedexpansion
for /d /r "x:\target\folder" %%a in (*) do for /f "tokens=1,5" %%b in ('
dir /a-d "%%~fa.\*" 2^> nul ^| findstr /b /c:" " ^|^| echo 0
') do if "%%c"=="" echo %%~fa : %%b
Run Code Online (Sandbox Code Playgroud)
这会
for /r /d)下的每个文件夹,获取一个引用并将其存储在%%a可替换参数中dir使用文件夹的完整路径运行命令%%~fa|) 过滤列表以仅检索以两个空格开头的行(页脚行)dir命令失败),则输出 0dir | findstr处理for /f。我们将读取第一个标记(在适当的行中的文件数)和第五个(仅存在于带有目录信息的页脚行中)这种方法的问题dir | findstr是对每个子文件夹执行。这将使这比robocopy解决方案慢。
它可以更快,但需要更多的代码
@echo off
setlocal enableextensions disabledelayedexpansion
set "root=%cd%"
set "folder="
for %%r in ("%root%") do (
set "rootDrive=%%~dr\"
if not defined rootDrive set "rootDrive=\\"
for /f "delims=" %%a in ('
dir /s /a "%%~fr.\*" 2^>nul ^| findstr /r /c:"^ " /c:"^ .*\\."
') do for /f "tokens=1,* delims=\" %%b in ("%%~a") do if not "%%c"=="" (
set "folder=%%c"
) else if defined folder (
for /f %%d in ("%%~a") do (
setlocal enabledelayedexpansion
echo(!rootDrive!!folder! : %%d
endlocal
)
set "folder="
)
)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我们将只执行一个dir命令来检索完整列表并使用列表过滤findstr以仅检索具有文件夹名称和每个文件夹页脚的行。
代码将for /f %%a在此列表上迭代 ( )。当找到一个文件夹行(它包含一个反斜杠并且可以用 分隔for /f %%b)时,文件夹名称保存在一个变量中。当读取到对应的footer行时(没有被反斜杠分割),分割行得到文件for /f %%d数(变量内容,因为它们被设置在同一个循环中)
注意:使用 afor /f处理通过执行命令生成的大量数据列表可能非常慢(命令处理内存的方式存在不良行为)。对于这种情况,有必要首先执行生成数据的命令(dir | findstr在这种情况下)将其输出发送到文件,然后使用for /f来处理文件。
@echo off
setlocal enableextensions disabledelayedexpansion
set "root=%~1"
if not defined root for %%a in (.) do set "root=%%~fa"
set "folder="
for %%t in ("%temp%\%~nx0.%random%%random%.tmp") do for %%r in ("%root%") do (
set "rootDrive=%%~dr\"
if not defined rootDrive set "rootDrive=\\"
( dir /s /a "%%~fr.\*" 2^> nul | findstr /r /c:"^ " /c:"^ .*\\." ) > "%%~ft"
for /f "usebackq delims=" %%a in ("%%~ft") do (
for /f "tokens=1,* delims=\" %%b in ("%%~a") do if not "%%c"=="" (
set "folder=%%c"
) else if defined folder (
for /f %%d in ("%%~a") do (
setlocal enabledelayedexpansion
echo(!rootDrive!!folder! : %%d
endlocal
)
set "folder="
)
)
del /q "%%~ft"
)
Run Code Online (Sandbox Code Playgroud)
编辑以适应评论:robocopy解决方案更改为包括文件总数
@echo off
setlocal enableextensions disabledelayedexpansion
set "total=0"
pushd "x:\target\folder" && (
for /f "tokens=1,*" %%a in ('
robocopy . . /l /nocopy /is /e /nfl /njh /njs
') do (
echo %%~fb : %%a
set /a "total+=%%a"
)
popd
)
echo Total files: %total%
Run Code Online (Sandbox Code Playgroud)