Как перебирать имена папок и перемещать папки на основе даты в имени папки?

#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 /?