Во-первых, как объясняется в статье Microsoft Именование файлов, путей и пространств имен , разделитель каталогов в Windows равен \
, а не /
, как в Linux / Mac./
используется в Windows для параметров, как вы можете видеть в своем коде, например, на /Q
.Так что используйте в будущем \
в путях к файлам / папкам.Доступ к функциям ядра в файловой системе Windows автоматически заменяет все прямые косые черты перед обращением к файловым системам, но написание кода в зависимости от автоматического исправления ошибок никогда не является хорошей идеей.
Задача удаления всех папок с именем log
или log-archive
в указанной папке и во всех ее подпапках можно выполнить с помощью одной командной строки.
@for /F "delims=" %%I in ('dir "%ProgramFiles%\product\plugins\plugin_Path\log*" /AD /B /S 2^>nul ^| %SystemRoot%\System32\findstr.exe /E /I /R "\\log \\log-archive"') do @rd /Q /S "%%I" 2>nul
FOR с параметром /F
запускается в отдельном командном процессе, запущенномс cmd.exe /C
(точнее с %ComSpec% /C
) в фоновом режиме командная строка в '
... '
, которая находится здесь:
dir "C:\Program Files\product\plugins\plugin_Path\log*" /AD /B /S 2>nul | C:\Windows\System32\findstr.exe /E /I /R "\\log \\log-archive"
Команда DIR выводитдля обработки STDOUT
- в голом формате из-за опции
/B
- только каталоги из-за опции
/AD
(каталог атрибутов) - имена каталогов, соответствующие шаблону подстановки
log*
- в указанном каталоге
C:\Program Files\product\plugins\plugin_Path
- и всех его подкаталогах из-за опции
/S
- с полным путем такжеиз-за опции
/S
.
Возможно, DIR не найдет ни одной записи файловой системы, соответствующей этим критериям.В этом случае сообщение об ошибке выводится DIR для обработки STDERR .Этот вывод ошибок перенаправляется с помощью 2>nul
на устройство NUL для его подавления.
Стандартный вывод DIR перенаправляется с помощью |
для обработки STDIN из FINDSTR , который запускается
- из-за опции
/I
без учета регистра - регулярное выражение находит явно запрашиваемый с параметром
/R
- для строки
\log
или \log-archive
(пробел интерпретируется как ИЛИ) - , который должен быть найден в конце строки из-за опции
/E
.
Все строки, соответствующие этим критериям поиска, выводятся с помощью FINDSTR для обработки STDOUT процесса фоновой команды.Эта фильтрация вывода DIR с FINDSTR необходима, чтобы избежать удаления каталога, имя которого, например, LogToKeep
также найдено и выведено DIR .
Прочтите статью Microsoft о Использование операторов перенаправления команд для объяснения 2>nul
и |
.Операторы перенаправления >
и |
должны быть экранированы с помощью символа вставки ^
on FOR , чтобы интерпретировать их как буквенные символы, когда интерпретатор команд Windows обрабатывает эту командную строку перед выполнением команды FOR, который выполняет встроенную командную строку в отдельном командном процессе, запущенном в фоновом режиме.
FOR с опцией /F
захватывает выходные данные для обработки STDOUT запущенного командного процесса и обрабатывает этот вывод построчно после завершения самого запуска cmd.exe
.Пустые строки всегда игнорируются FOR , которые здесь не встречаются.Строки, начинающиеся с точки с запятой, также по умолчанию игнорируются, поскольку eol=;
является значением по умолчанию для параметра конца строки.Но полный путь к папке не может содержать точку с запятой в начале, потому что путь к папке начинается с буквы диска или с обратной косой чертой в случае UNC-пути.Таким образом, опция конца строки по умолчанию может быть сохранена в этом случае. FOR будет по умолчанию разделять каждую строку на подстроки с использованием обычного пробела и горизонтальной табуляции в качестве разделителей строк и назначать только первую строку, разделенную пробелом / табуляцией, указанной переменной цикла.Такое разделение строк здесь нежелательно, поскольку путь к папке определенно содержит символ пробела, и нужен весь путь к папке, а не только строка до первого пробела.По этой причине delims=
используется для указания пустого списка разделителей, который запрещает разделение строк.
FOR выполняется для каждого вывода каталога при DIR передаче FINDSTR фильтрует по полному пути команду RD для тихого удаления каталога из-за опции /Q
и со всеми файлами и подкаталогами из-за /S
.
Удалениеможет произойти сбой каталога из-за отсутствия разрешений NTFS, или каталог для удаления, или один из его подкаталогов является текущим каталогом запущенного процесса, или файл в каталоге, который нужно удалить, в данный момент открывается запущенным процессом способом, который запрещает удалениефайл при открытии или каталог для удаления больше не существует, поскольку он был удален уже ранее в цикле FOR .Сообщение об ошибке, выводимое командой RD для обработки STDERR , в этом случае перенаправляется на устройство NUL для его подавления.
Обратите внимание, что команда RD удаляет все каталоги log
и log-archives
, а не только файлы и подкаталоги в этих каталогах.Из вашего вопроса неясно, что именно должно быть удалено командным файлом.
Конечно, также можно заменить rd /Q /S "%%I"
на del /A /F /Q "%%I\*"
, чтобы спокойно удалить только все файлы, включая скрытые и доступные только для чтения.в каталоге с полным путем к переменной цикла I
.
@
слева от команды FOR и команды RD просто подавить вывод этих команд передвыполнение командным процессором Windows cmd.exe
.Оба @
не нужны, если эта единственная командная строка используется в пакетном файле, содержащем до @echo off
.
Чтобы понять используемые команды и то, как они работают, откройте окно командной строки и выполните там следующеекоманды и полностью прочитайте все страницы справки, отображаемые для каждой команды.
del /?
dir /?
findstr /?
for /?
rd /?