gpt4 book ai didi

windows - 在 Windows 批处理文件中查找文件并按大小排序

转载 作者:可可西里 更新时间:2023-11-01 11:09:53 24 4
gpt4 key购买 nike

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

到目前为止我已经这样做了,但它不起作用:

::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

最佳答案

既然这个学期已经过去很久了,我回答这个家庭作业问题并不感到内疚。 Print folders and files recursively using Windows Batch是一个讨论作业的封闭式重复问题。

我最初的解决方案相当简单。有一些技巧可以确保它正确处理其中包含特殊字符的路径,但不要太花哨。唯一的其他技巧是用空格填充文件大小,以便 SORT 正常工作。

与原题一样,第一个参数应该是一个文件夹路径(.\可以正常工作),后面的参数代表文件名(可以使用通配符)。

@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

我曾希望通过直接用管道替换重定向和后续排序来避免创建临时文件。但这不起作用。 (参见我的相关问题:Why does delayed expansion fail when inside a piped block of code?)

我的第一个解决方案运行良好,但根据提供的输入可能会出现重复输出。我决定编写一个版本来清除重复的文件报告。

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

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

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

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

通常 FOR 变量的范围严格在循环内。如果您在循环外调用 CALL,则 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

关于windows - 在 Windows 批处理文件中查找文件并按大小排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5607489/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com