在Windowsbatch file中查找文件并按大小sorting

我有我的批处理脚本命令行参数的文件名和文件夹的列表。 对于每个文件名,我需要打印find该文件的文件夹的所有子文件夹(该文件的path)。 子文件夹名称应按文件大小的降序排列(文件在不同的子文件夹中可以有不同的大小)。

到目前为止,我已经完成了这个工作,但是这不起作用:

::verify if the first parameter is the directory @echo off REM check the numbers of parameters if "%2"=="" goto err1 REM check: is first parameter a directory? if NOT EXIST %1\NUL goto err2 set d=%1 shift REM iterate the rest of the parameters for %%i in %dir do ( find %dir /name %i > temp if EXIST du /b temp | cut /f 1 goto err3 myvar=TYPE temp echo "file " %i "is in: " for %%j in %myvar do echo %j echo after sort du /b %myvar | sort /nr ) :err1 echo Two parameters are necessary goto end :err2 echo First parameter must be a directory. goto end :err3 echo file does not exist. goto end :end 

Solutions Collecting From Web of "在Windowsbatch file中查找文件并按大小sorting"

现在这个学期已经过去了,我不觉得内疚地回答这个作业问题。 使用Windows Batch递归地打印文件夹和文件是一个封闭的重复问题,讨论分配。

我最初的解决方案非常简单。 有一些技巧,以确保它正确处理与特殊字符的路径,但没有太花哨。 唯一的另一个技巧是用空格填充文件大小,以便SORT正常工作。

就像在原来的问题一样,第一个参数应该是一个文件夹路径(。\工作得很好),后面的参数代表文件名(通配符是OK)。

 @echo off setlocal disableDelayedExpansion set tempfile="%temp%\_mysort%random%.txt" set "root=" for %%F in (%*) do ( if not defined root ( pushd %%F || exit /b set root=1 ) else ( echo( echo %%~nxF echo -------------------------------------------- ( @echo off for /f "eol=: delims=" %%A in ('dir /s /b "%%~nxF"') do ( set "mypath=%%~dpA" set "size= %%~zA" setlocal enableDelayedExpansion set "size=!size:~-12!" echo !size! !mypath! endlocal ) ) >%tempfile% sort /r %tempfile% ) ) if exist %tempfile% del %tempfile% if defined root popd 

我希望避免创建一个临时文件,通过直接替换重定向和随后的排序来排序。 但是这不起作用。 (请参阅我的相关问题: 为什么在管道代码块内部延迟扩展失败? )

我的第一个解决方案运行良好,除了有可能重复输出取决于提供的输入。 我决定我会写一个版本,删除重复的文件报告。

基本前提很简单 – 将所有输出保存到一个临时文件中,并将文件名添加到已排序字符串的前面。 然后,我需要遍历结果,并只在文件和/或路径更改时打印信息。

最后一个循环是棘手的部分,因为文件名可以包含特殊字符! ^ &% ,这可能会导致问题取决于使用什么类型的扩展。 我需要设置和比较循环内的变量,这通常需要延迟扩展。 但是延时扩展会导致FOR变量扩展时出现问题! 被发现。 我可以通过调用外部循环来避免延迟扩展,但是然后FOR变量变得不可用。 我可以将变量作为参数传递给CALLed例程而不会延迟扩展,但是后来遇到了% ^& 。 我可以用SETLOCAL / ENDLOCAL玩游戏,但是我需要担心通过ENDLOCAL屏障传递值,这需要一个相当复杂的转义过程。 这个问题变成了一个很大的恶性循环。

另一个自我强加的约束是我不想用引号括起文件和路径输出,这意味着我必须使用延迟扩展,FOR变量或转义值。

我发现了一个有趣的解决方案,它利用了FOR变量的一个奇特的特性。

通常,FOR变量的范围严格限制在循环内。 如果您在循环外部调用,那么FOR变量值将不再可用。 但是,如果你在被调用的过程中发出FOR语句 – 调用者FOR变量就会变成可见的! 问题解决了!

 @echo off setlocal disableDelayedExpansion set tempfile="%temp%\_mysort%random%.txt" if exist %tempfile% del %tempfile% set "root=" ( for %%F in (%*) do ( if not defined root ( pushd %%F || exit /b set root=1 ) else ( set "file=%%~nxF" for /f "eol=: delims=" %%A in ('dir /s /b "%%~nxF"') do ( set "mypath=%%~dpA" set "size= %%~zA" setlocal enableDelayedExpansion set "size=!size:~-12!" echo(!file!/!size!/!mypath! endlocal ) ) ) )>%tempfile% set "file=" set "mypath=" for /f "tokens=1-3 eol=/ delims=/" %%A in ('sort /r %tempfile%') do call :proc if exist %tempfile% del %tempfile% if defined root popd exit /b :proc for %%Z in (1) do ( if "%file%" neq "%%A" ( set "file=%%A" set "mypath=" echo( echo %%A echo -------------------------------------------- ) ) for %%Z in (1) do ( if "%mypath%" neq "%%C" ( set "mypath=%%C" echo %%B %%C ) ) exit /b