Очистка нескольких каталогов - оптимизировать текущий код - PullRequest
0 голосов
/ 20 января 2019

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

Ниже приведен мой текущий код.

@echo off

DEL /A /F/Q /S "C:\Users\Testing\Documents\*.*"
FOR /D %%p IN ("C:\Users\Testing\Documents\*.*")  DO RD "%%p" /S /Q
DEL /A /F/Q /S "C:\Users\Testing\Downloads\*.*"
FOR /D %%p IN ("C:\Users\Testing\Downloads\*.*")  DO RD "%%p" /S /Q
DEL /A /F/Q /S "C:\Users\Testing\My Pictures\*.*"
FOR /D %%p IN ("C:\Users\Testing\My Pictures\*.*")  DO RD "%%p" /S /Q

Ответы [ 2 ]

0 голосов
/ 20 января 2019

Прежде всего, команда RD /S /Q удалит все файлы в подкаталогах, поэтому вы можете удалить опцию /S из команды DEL.

Теперь к вашему актуальному вопросу - конечно, есть лучший способ: -)

Общее решение для произвольно сложного кода состоит в том, чтобы поместить весь общий код в подпрограмму, которая принимает один или несколько аргументов, а затем вызвать подпрограмму для каждого набора уникальных аргументов. Не забудьте включить exit /b перед любой из ваших подпрограмм, чтобы ваш основной сценарий не попадал в код подпрограммы без выполнения вызова.

@echo off
call :del "C:\Users\Testing\Documents"
call :del "C:\Users\Testing\Downloads"
call :del "C:\Users\Testing\My Pictures"
exit /b

:del
del /a /f /q /s "%~1\*.*"
for /d %%p in ("%~1\*.*") do rd /s /q "%%p"
exit /b

Если вы хотите, вы можете добавить дополнительный цикл FOR для итерации ваших файлов, и тогда вам нужен только один оператор CALL.

@echo off
for %%P in (
  "C:\Users\Testing\Documents"
  "C:\Users\Testing\Downloads"
  "C:\Users\Testing\My Pictures"
) do call :del %%P
exit /b

:del
del /a /f /q /s "%~1\*.*"
for /d %%p in ("%~1\*.*") do rd /s /q "%%p"
exit /b

Но поскольку ваш общий код очень прост, я рекомендую переместить код подпрограммы во внешний блок DO, добавив скобки:

@echo off
for %%P in (
  "C:\Users\Testing\Documents"
  "C:\Users\Testing\Downloads"
  "C:\Users\Testing\My Pictures"
) do (
  del /a /f /q /s "%%~P\*.*"
  for /d %%p in ("%%~P\*.*") do rd /s /q "%%p"
)

Это на самом деле не уменьшает количество строк в вашем случае, но делает повторяющуюся природу вашего сценария более очевидной и более легкой в ​​управлении. И это сократит количество строк кода при добавлении новых путей во внешний цикл.

0 голосов
/ 20 января 2019
@echo off
    setlocal enableextensions disabledelayedexpansion

    for %%a in ( 
        "C:\Users\Testing\Documents" 
        "C:\Users\Testing\Downloads" 
        "C:\Users\Testing\My Pictures"
    ) do pushd %%a && (
        rmdir . /s /q
        popd
    )

Использование команды for для просмотра списка папок.Для каждой папки в списке попробуйте изменить активный каталог на текущий элемент в списке (pushd) и, если это возможно (оператор условного выполнения &&), удалить что-либо внутри (rmdir . /s /q) и восстановить предыдущий активный каталог (popd)

note В предыдущем коде rmdir . /s /q пытается удалить что-либо внутри папки И самой папки.Папка не может быть удалена, так как мы установили ее в качестве текущего активного каталога с помощью pushd.Как указано в комментариях dbenham, это означает, что rmdir покажет сообщение об ошибке, в котором говорится, что папку нельзя удалить, поскольку она используется.Хотя это предполагаемое поведение (защита папки, а не сообщение об ошибке), возможно, желательно скрыть сообщение об ошибке.Это можно сделать, перенаправив поток вывода ошибок (поток 2) на устройство nul:

    ...
    ) do pushd %%a && (
        rmdir . /s /q 2>nul 
        popd
    )

Это позволит скрыть любую ошибку (ожидаемую или нет), связанную с командой rmdir.

Эта техника может быть расширена, чтобы скрыть любую ошибку в предыдущем коде (если вы включите несуществующую папку, pushd также показывает ошибку).

@echo off
    setlocal enableextensions disabledelayedexpansion

    2>nul (
        for %%a in ( 
            "C:\Users\Testing\Documents" 
            "C:\Users\Testing\Downloads" 
            "C:\Users\Testing\My Pictures"
        ) do pushd %%a && (
            rmdir . /s /q
            popd
        )
    )

Или, если вы предпочитаете выборочное сообщение об ошибке (идея dbenham), его можно расширить как:

@echo off
    setlocal enableextensions disabledelayedexpansion

    for %%a in ( 
        "C:\Users\Testing\Documents" 
        "C:\Users\Testing\Downloads" 
        "C:\Users\Testing\My Pictures"
    ) do ( 2>nul pushd "%%~a" ) && (
        rmdir . /s /q 2>&1 | findstr /lb "."
        popd
    )

, который будет скрывать ошибки в команде pushd (еслипапка не существует, ее не нужно чистить), и в команде rmdir будут отображаться ошибки, связанные с любым несъемным элементом, кроме текущего активного каталога.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...