2

Изменить: После ответа @Mbu я понял, что мой первый подход с ведущими числами в папках в качестве критериев для исключения не является правильным способом. Я решил использовать фиксированный список папок для исключения.


Я хочу удалить определенные файлы с помощью пакета, но исключить заданный набор путей для проверки

Пример структуры

E:.
|───MyBatchFile.cmd
|
├───yes
│   │   no.doc        | file has wrong extension
│   │   yes.cfg
│   │   yes.dat
│   │   yes.hgr
│   │
│   └───yes
│           yes.cfg
│           yes.dat
│           yes.hgr
│
├───yes
│       yes.cfg
│       no.dat        | file is too new, modified within a year
│       no.hgr        | file is too new, modified within a year
│
|───no1               | folder is on blacklist
|       importantstuff
│
└───no2               | folder is on blacklist
        importantstuff

Имена файлов yes и no показывают, какие файлы должны быть удалены

Что я хочу

Поиск всех файлов во всех папках и подпапках, начиная с папки, в которой находится пакет. Если выполняются все следующие условия, удалите файл

  1. расширение файла .cfg, .dat, .hgr или .txt
  2. модифицированное время более 365 дней
  3. Путь не в черном списке

Что я пробовал

Исходя из этого вопроса, у меня есть:

@echo off
for %%i in (.cfg, .dat, .hdr, .txt) do (
  forfiles /s /m *%%i /d -365 /c "cmd /c del @path"
)
pause

Два из трех вопросов решены, но как исключить данный набор папок.
Как E:\no1 и E:\no2 из моего примера.

2 ответа2

2

Вы можете попробовать этот скрипт, но он будет работать, только если %%~tA в ваших региональных настройках возвращает дату файла в формате YMD. Если нет, сравнение не будет работать, как ожидалось.

@Echo Off
setlocal enabledelayedexpansion

for /r %%A in (*.cfg;*.dat;*.hdr) do (
  set p=%%~pA
  set numeric=no
  if "!p:~1,1!"=="0" set numeric=yes
  if "!p:~1,1!"=="1" set numeric=yes
  if "!p:~1,1!"=="2" set numeric=yes
  if "!p:~1,1!"=="3" set numeric=yes
  if "!p:~1,1!"=="4" set numeric=yes
  if "!p:~1,1!"=="5" set numeric=yes
  if "!p:~1,1!"=="6" set numeric=yes
  if "!p:~1,1!"=="7" set numeric=yes
  if "!p:~1,1!"=="8" set numeric=yes
  if "!p:~1,1!"=="9" set numeric=yes

  if !numeric!==yes (
    if "%%~tA" LSS "2012-11-08" (
      del %%A
    )
  )
)

endlocal

РЕДАКТИРОВАТЬ

Я думаю, что мне удалось изменить сценарий, чтобы работать так, как вы хотите. Мне пришлось избавиться от ключа /r и рекурсивно вызвать подпрограмму, иначе черный список не будет работать должным образом. Черный список должен храниться в файле blacklist.txt в том же каталоге, где находится скрипт. Файл должен содержать полные пути к исключенным папкам без кавычек:

D:\excluded folder1
D:\excluded folder2
D:\included folder\excluded folder3

Для каждой папки, не занесенной в черный список, вызывается подпрограмма, которая ищет файлы по расширению, а затем дата каждого файла сравнивается с указанной датой. Пожалуйста, тщательно проверьте сценарий. Я боюсь, что это может сломаться на именах папок, содержащих специальные символы, такие как % или ^ .

@Echo Off
call :browse D:
goto :EOF

:browse
for /d %%A in ("%~1\*") do (
  find /i "%%A" %~dp0blacklist.txt > nul
  if errorlevel 1 (
    call :delete "%%A"
    call :browse "%%A"
  ) else (
    echo SKIP %%A
  )
)
goto :EOF

:delete
for %%A in ("%~1\*.cfg" "%~1\*.dat" "%~1\*.hdr") do (
  if "%%~tA" LSS "2012-10-08" (
    echo DEL  %%A
    del "%%A"
  ) else (
    echo SAVE %%A
  )
)
goto :EOF
1

Я думаю, что ответ MBu лучше, чем мой, поскольку он не зависит от внешнего инструмента, такого как Robocopy. И если список папок в черном списке будет расти, моя команда Robocopy будет выглядеть ужасно. Тем не менее я хочу поделиться тем, что нашел.

Вы можете неправильно использовать Robocopy для удаления старых файлов, фильтрации определенных расширений и исключения нескольких каталогов из сканирования - все в одной команде.

md C:\TrashMe 
robocopy C:\ C:\TrashMe *.cfg *.hdr *.txt *.dat /MOVE /E /MINAGE:365 /CREATE /R:1 /W:1 /XD C:\dir1 C:\dir2 C:\TrashMe
rd C:\TrashMe

Пакет создаст временную папку для мусора с именем TrashMe .
Робокопия будет чем двигаться (не копировать!) все нужные файлы (правильное расширение и измененная метка времени старше 365 дней) в эту папку корзины. Вы исключаете несколько папок с помощью ключа /XD .
Последнее действие - удалить папку мусора, содержащую все найденные старые файлы.

Хитрость заключается в том, чтобы использовать ключ /CREATE чтобы robocopy создавал файлы нулевого байта вместо реального исходного файла. Это ускоряет команду перемещения и удаления детали.


Команда Robocopy подробно

  • robocopy вызывает C:\Windows\System32\Robocopy.exe, который предустановлен в Windows Server 2003, Vista, 7 и 8
  • C:\ - исходная папка, которая должна быть проверена
  • C:\TrashMe является (временной) целевой папкой для всех найденных файлов
  • *.cfg *.hdr *.txt *.dat являются подстановочными знаками и будут фильтровать для определенных расширений файлов.
  • /MOVE вырезает и вставляет все найденные файлы вместо того, чтобы копировать и вставлять их
  • /E будет сканировать все подкаталоги
  • /MINAGE:365 исключит все файлы, которые новее 365 дней
  • /CREATE создаст файлы с нулями вместо исходного исходного файла
  • /R:1 /W:1 - количество повторных попыток и время ожидания, если файл заблокирован и не может быть удален
  • /XD C:\dir1 C:\dir2 C:\TrashMe - мой список папок в черном списке. Я должен был также включить папку TrashMe, потому что она находится в исходной папке

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .