forfiles命令忽略一个目录

3
我希望编写一个批处理程序,可以在中查找所有小于50 mb的文档,并将它们复制到一个文件夹中,但忽略系统目录文档。我希望它甚至不要搜索系统目录。以下是我的批处理程序,可以在正确的目录中查找并复制所有小于50 mb的文件,但我无法使其忽略系统目录或目录的搜索。
@ECHO off
:: variables

SET odrive=%odrive:~0,2%
SET backupcmd=xcopy /s /c /d /e /h /i /r /y

MKDIR "C:\Users\Documents\USBBackups\DOC\C"

forfiles /P C:\ /M *.DOC* /S /C "cmd /c if @fsize leq 50000000 echo @PATH "  > "C:\Users\Documents\USBBackups\DOCC.txt"
FOR /F "tokens=*" %%a in (C:\Users\Documents\USBBackups\DOCC.txt) do xcopy %%a "C:\Users\Documents\USBBackups\DOC\C" /c /h /i /r /y

@ECHO off
2个回答

4
当使用/S开关时,无法告诉forfiles排除某些目录。你需要编写自己的代码来实现这一点。我不会使用forfiles,因为性能较差,而应该使用标准的for
@echo off
for /D %%D in ("%SystemDrive%\*.*") do (
    if /I not "%%D"=="%SystemRoot%" (
        pushd "%%D"
        for /R %%F in ("*.doc?") do (
            if %%~zF LEQ 50000000 (
                echo %%F
            )
        )
        popd
    )
)

这里使用for /D枚举根目录级别。除了%SystemRoot%之外的所有目录都是通过for /R递归枚举的。

我将搜索模式从*.doc*更改为*.doc?,以便不包括以.doc.lnk结尾的文件,例如,我猜您不希望检索到这些文件。

您可以直接在xcopy命令行中使用"%%F"作为复制源,而不是使用echo命令。


您可以在命令提示符中直接使用一行命令来完成相同的操作,如下所示:

for /D %D in ("%SystemDrive%\*.*") do @if /I not "%D"=="%SystemRoot%" pushd "%D" & (for /R %F in ("*.doc?") do @if %~zF LEQ 50000000 echo %F) & popd

我建议不要遍历整个目录树,然后再通过类似 findstr /V /I /L /B /C:"%SystemRoot%" 这样的方式进行筛选,因为在这种情况下,您将浪费时间枚举大量之后要忽略的项目。

但是,如果您确实想依赖于 forfiles /S,则工作命令行如下:

2> nul forfiles /S /P "C:\\" /M "*.doc*" /C "cmd /C if @isdir==FALSE if @fsize LEQ 50000000 echo @path" | findstr /V /I /L /B /C:"\"%SystemRoot%"

非常感谢您的帮助。您有什么增加代码性能和速度的技巧吗? - M.shadow
不客气!我无法通过嵌套的“for”循环来提高方法的性能;但是,为了使它更快,您可以考虑排除更多文件夹(例如“C:\Program Files”);或者另一个想法是不要排除某些文件夹,而是仅包括专用文件夹,因为这也可能减少总文件夹数... - aschipfl
顺便感谢你的提示,我想问一下如何将你的一行代码(for /D ...)的结果保存到一个 .txt 文件中,就像我的 forfiles 代码中那样。我真的尝试过了,但它在每个循环中都会覆盖记事本。 - M.shadow
抱歉打扰了,当我将其作为批处理文件运行时,出现以下错误:“批处理参数替换中路径运算符的以下用法无效:%~zF LEQ 50000000 echo %F( & popd) >“C:\Users\Documents\USBBackups\DOCC.txt””。 - M.shadow
如果您在批处理文件中使用此行,则需要将除SystemRootSystemDrive周围的所有%符号都加倍;这是因为for--在命令提示符窗口中键入for /?并阅读帮助文本,其中提到了这一点...但单行代码与我的第一个代码片段基本相同... - aschipfl
显示剩余3条评论

0

使用findstr过滤特定名称的技巧可以进行调整。

查看文档文件夹的大小,但不包括音乐、视频或图片文件夹。

for /f "skip=3 tokens=3" %A in ('Reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v "Personal"') do set doc=%A

for /f "usebackq tokens=2* delims= " %i IN (`dir "%doc%" /a /s ^|findstr /i /v "\/"^|findstr /l /v "Pictures Music Video"`) DO @echo %j&echo.

不过,您可以在c:\users或特定用户的主文件夹(%userprofile%)中启动forfiles命令。您可以指定从c:\开始,这将包括所有文件夹。

forfiles /P %userprofile% /M .DOC /S /C "cmd /c if @fsize leq 50000000 echo @PATH "
forfiles /P c:\users /M .DOC /S /C "cmd /c if @fsize leq 50000000 echo @PATH "

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接