2016-01-12 9 views
1

Я хочу написать партию, которая находит все документы менее 50 мб в c:\ и копирует их в папку , но игнорирует системный каталог документов. Я предпочитаю, чтобы он даже не искал в системном каталоге.команда forfiles игнорировать каталог

Вот моя партия, которая находит и копирует все файлы менее 50 мб в правый каталог, но я не могу заставить его игнорировать систему из поиска или C:\Windows.

@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

Там нет никакого способа сказать forfiles исключить определенные каталоги, когда переключатель /S предусмотрен. Вам нужно будет написать свой собственный код, который сделает это.

Я бы не использовать 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, например, которые, я думаю, вы не хотите получать.

Вместо команды echo вы можете разместить свою xcopy командную строку с номером "%%F" в качестве источника копирования.


Вы можете сделать то же самое непосредственно в командной строке как однострочник, например:

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%" 
+0

Большое спасибо за вашу помощь. у вас есть подсказка для повышения производительности и скорости кода. –

+0

Добро пожаловать!Я не могу улучшить производительность подхода, используя вложенные петли 'for'; однако, чтобы сделать это быстрее, вы могли бы исключить больше папок (например, 'C: \ Program Files'); или другая идея состоит в том, чтобы не исключать (а) определенные папки, но включать только выделенные папки, потому что это также может уменьшить общее количество папок ... – aschipfl

+0

спасибо за подсказку, кстати, как я могу сохранить результат ваш однострочный код (для/D ...) в файл .txt, такой как файл в моем коде forfiles. я действительно пытался, но он перезаписывал блокнот в каждом цикле. –

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. 

Однако вы могли бы начать Forfiles команду в c:\users или в домашней папке конкретных пользователей (%userprofile%). Вы указываете, чтобы начать с 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 " 
Смежные вопросы