#windows #batch-file #cmd
Вопрос:
В настоящее время у меня есть пакетный файл, который просматривает текстовый файл со списком имен файлов и перемещает эти файлы в папки на основе даты в имени файла.
Сейчас я пытаюсь изменить это, чтобы сделать что-то подобное, но для папок. Получите имена папок, а затем переместите каждую папку в другое место на основе даты в имени папки.
Пример структуры папок:
Перед переездом:
k:PLPR1
k:PLPR120210910data
k:PLPR120210909data
k:PLPR120210830data
После переезда:
l:PLPR12021FTP DataSeptember10 Septemberdata
l:PLPR12021FTP DataSeptember9 Septemberdata
l:PLPR12021FTP DataSeptember30 Augustdata
Ответ №1:
Задачу перемещения папки можно выполнить с помощью следующего пакетного файла:
@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "SourcePath=K:PLPR1"
set "TargetPath=L:PLPR1"
set "Month01=January"
set "Month02=February"
set "Month03=March"
set "Month04=April"
set "Month05=May"
set "Month06=June"
set "Month07=July"
set "Month08=August"
set "Month09=September"
set "Month10=October"
set "Month11=November"
set "Month12=December"
for /F "delims=" %%I in ('dir "%SourcePath%" /AD-L /B 2^>nul') do (
set "FolderName=%%I"
set "Year=!FolderName:~0,4!"
set "Month=!FolderName:~4,2!"
set "Day=!FolderName:~6,2!"
for %%I in (Month!Month!) do set "Month=!%%I!"
%SystemRoot%System32robocopy.exe "%SourcePath%%%I" "%TargetPath%!Year!FTP Data!Month!!Day! !Month!" /E /MOVE /NDL /NFL /NJH /NJS /R:1 /W:5 >nul
)
endlocal
Первые две командные строки определяют требуемую среду выполнения, которая:
- режим эхо-команды отключен
- включены расширения команд
- включено расширение переменной среды с задержкой
Включенное отложенное расширение означает, что этот пакетный файл нельзя использовать без изменений в исходном или целевом пути, содержащем один или несколько восклицательных знаков.
Кроме того, этот код пакетного файла предполагает, что исходная папка содержит только вложенные папки, имена которых являются датой в формате yyyyMMdd
.
Использование for /F
с командной строкой, заключенной в '
, приводит к запуску в фоновом режиме еще одной cmd.exe
опции с /c
и указанной командной строкой, добавленной в качестве дополнительных аргументов. Таким образом, выполняется в фоновом режиме с установленной Windows для C:Windows
:
C:WindowsSystem32cmd.exe /c dir "K:PLPR1" /AD-L /B 2>nul
Прочтите документацию Microsoft об использовании операторов перенаправления команд для объяснения 2>nul
. Оператор перенаправления >
должен быть экранирован символом курсора ^
, чтобы командная строка интерпретировалась как буквальный символ, когда интерпретатор команд Windows обрабатывает эту командную строку перед выполнением команды, для которой выполняется встроенная dir
командная строка в отдельном командном процессе, запущенном в фоновом режиме.
Команда DIR выполняет поиск
- в указанном каталоге для записей файловой системы, которые
- имеют набор атрибутов каталога и не являются точками повторного анализа (соединениями каталогов) из-за опции
/AD-L
и - выводит в голом формате только имена папок из-за опции
/B
без пути.
Сообщение об ошибке, выводимое DIR при не нахождении какого-либо каталога, подавляется перенаправлением на устройство NUL.
Вывод DIR для обработки вывода фоновой команды процесса фиксируется для соответствующей cmd.exe
обработки пакетного файла и обрабатывается построчно после запуска cmd.exe
и закрывается после завершения выполнения DIR.
ДЛЯ параметра with /F
всегда игнорируются пустые строки, которые здесь вообще не встречаются. Непустая строка по умолчанию будет разделена на подстроки, используя обычный пробел и горизонтальную вкладку в качестве разделителей строк. Такое поведение разделения строк здесь не будет проблемой, поскольку имена папок в формате yyyyMMdd
не содержат пробелов, но, тем не менее, используется delims=
для определения пустого списка разделителей строк, что делает обработку имен файлов немного быстрее, так как в этом случае поведение разделения строк отключено.
Если бы первая подстрока, являющаяся теперь полным именем каталога, начиналась с точки с запятой, FOR также игнорировал бы захваченную строку для дальнейшей обработки. Это поведение в конце строки здесь не имеет значения, поскольку имена каталогов не начинаются с точки с запятой.
Таким образом, в памяти командного процесса, обрабатывающего пакетный файл, теперь есть список имен каталогов, которые назначаются одно за другим указанной переменной цикла I
, и больше не имеет значения, что произойдет дальше в исходном каталоге во время итераций цикла. Это важно, особенно если исходный каталог находится на диске FAT (FAT32, exFAT).
Имя каталога без пути присваивается переменной среды, а затем используются замены с отложенным расширением, чтобы разделить дату в имени до года, месяца и дня в месяце.
Определены двенадцать переменных среды, которые содержат для каждого месяца двузначное значение месяца в конце имени переменной, соответствующее названию месяца. Простой цикл FOR используется для объединения фиксированной строки Month
со значением месяца, определенным из имени каталога.Переопределите переменную среды Month
, используя отложенное расширение, именем месяца, присвоенным динамически создаваемой переменной среды, начиная Month
и заканчивая значением текущего месяца.
Теперь доступны все необходимые данные для перемещения всего внутри текущего каталога с помощью ROBOCOPY в соответствующий каталог назначения, используя значения года, месяца и дня. ROBOCOPY автоматически создает все дерево каталогов назначения (цели).
Конечно, возможно, что ROBOCOPY не удалит файл/каталог в исходном каталоге, например, если файл в данный момент открыт в исходном каталоге другим приложением или каталог является текущим каталогом запущенного процесса. Но это не имеет значения для цикла FOR, так как команда ДЛЯ себя больше не обращается к файловой системе для получения следующего имени каталога из-за обработки списка имен каталогов в памяти командного процесса. Таким образом, невозможно, чтобы какой-либо каталог обрабатывался более одного раза, или чтобы каталог был случайно пропущен, илиЦикл FOR превращается в бесконечный цикл благодаря тому, что сначала в память загружается список каталогов для обработки.
Для понимания используемых команд и того, как они работают, откройте окно командной строки, выполните в нем следующие команды и внимательно прочитайте все страницы справки, отображаемые для каждой команды.
dir /?
echo /?
endlocal /?
for /?
robocopy /?
set /?
setlocal /?