Попробуйте этот код командного файла:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceDir=%UserProfile%\Documents\NOTEPAD Coding\File Transfer Coding\Files"
set "DestDir=%UserProfile%\Documents\NOTEPAD Coding\File Transfer Coding\Transfer"
for /F "eol=| delims=" %%A in ('dir /B /A-D-H "%SourceDir%\*_????-??-??_*.pdf" 2^>nul') do (
for /F "eol=| tokens=1 delims=_" %%B in ("%%~nA") do (
for /D %%C in ("%DestDir%\%%B_*") do move /Y "%SourceDir%\%%A" "%%C\"
)
)
endlocal
Первый FOR выполняется в отдельном командном процессе, запущенном с cmd.exe /C
в фоновом режиме командной строки:
dir /B /A-D-H "C:\Users\Alpha\Documents\NOTEPAD Coding\File Transfer Coding\Files\*_????-??-??_*.pdf" 2>nul
DIR ищет в указанном каталоге
- только не скрытые файлы из-за
/A-D-H
(атрибут не каталог и не скрытый) - , соответствующийшаблон подстановки
*_????-??-??_*.pdf
, который также может быть просто *_*.pdf
- и выводить для обработки STDOUT в голом формате, поскольку
/B
только имена файлов с расширением файла, но без пути к файлу.
Сообщение об ошибке, выводимое DIR для обработки STDERR , если указанный каталог вообще не существует или отсутствует файл, соответствующий шаблону, подавляетсяперенаправив его с помощью 2>nul
на устройство NUL .
Прочтите также статью Microsoft о Использование операторов перенаправления команд для объяснения 2>nul
.Оператор перенаправления >
должен быть экранирован с помощью символа вставки ^
в FOR командной строке, чтобы интерпретироваться как литеральный символ, когда интерпретатор команд Windows обрабатывает эту командную строку перед выполнением команды FOR , котораявыполняет встроенную командную строку dir
в отдельном командном процессе, запущенном в фоновом режиме.
FOR захватывает все, записанное в STDOUT запущенного командного процесса, и обрабатывает захваченный выводстрока за строкой.
FOR по умолчанию игнорирует все пустые строки (здесь не встречаются) и все строки, начинающиеся с точки с запятой.Имя файла может начинаться с точки с запятой.По этой причине опция eol=|
используется для переопределения символа конца строки в вертикальной строке, которая не может содержать имя файла, см. Статью Microsoft о Именовании файлов, путей и пространств имен .
FOR разделяет также каждую строку на подстроки (токены), используя пробел / табуляцию в качестве разделителей, и назначает только первую строку, разделенную пробелом / табуляцией, указанной переменной цикла A
.Такое поведение разделения здесь нежелательно, поскольку имена файлов могут содержать один или несколько пробелов.Поэтому опция delims=
используется для определения пустого списка разделителей, который полностью запрещает разделение строк и приводит к присвоению полного имени файла с расширением переменной цикла A
.
Второй FOR обрабатывает только имя файла (без расширения) как строку.На этот раз имя файла разделяется с использованием подчеркивания в качестве разделителя из-за delims=_
с присвоением только первой строки с подчеркиванием для переменной цикла B
из-за tokens=1
.Ну, tokens=1
является значением по умолчанию при использовании for /F
, и поэтому эту строку параметров можно удалить из кода.
Так что первое FOR назначается A
, например RANSOM-NH_2018-08-07_5485A635.pdf
а второй FOR обрабатывает RANSOM-NH_2018-08-07_5485A635
и присваивает B
строку RANSOM-NH
.
Третий FOR с параметром /D
ищет нескрытые каталоги в целевом каталоге, начиная со строки, присвоенной переменной цикла B
и подчеркиванием.Если такой каталог найден, его имя с полным путем присваивается переменной цикла C
и выполняет команду MOVE .
Файл перемещается из исходного каталога в существующий подкаталог в целевом каталоге.с перезаписью существующего файла с тем же именем в целевой директории файла.
Второй цикл FOR может быть оптимизирован, когда нет файлов PDF, начинающихся с подчеркивания или имеющих болееодно подчеркивание перед частью даты.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SourceDir=%UserProfile%\Documents\NOTEPAD Coding\File Transfer Coding\Files"
set "DestDir=%UserProfile%\Documents\NOTEPAD Coding\File Transfer Coding\Transfer"
for /F "eol=| tokens=1* delims=_" %%A in ('dir /B /A-D-H "%SourceDir%\*_????-??-??_*.pdf" 2^>nul') do (
for /D %%C in ("%DestDir%\%%A_*") do move /Y "%SourceDir%\%%A_%%B" "%%C\"
)
endlocal
Опция tokens=1*
приводит к присвоению первой части имени файла, разделенной подчеркиванием, переменной цикла A
, а остальной части имени файла следующей переменной цикла B
в соответствии с ASCII таблица без дальнейшего разделения на подчеркивания.
Но учтите, что оптимизированная версия не работает для имен файлов, таких как
_RANSOM-X_2018-08-07_5485A635.pdf
... подчеркивание в начале или RANSOM-Y__2018-08-07_5485A635.pdf
... более одной детали подчеркивания, оставшейся до даты.
Оптимизированная версия может быть дополнительно оптимизирована для одной командной строки:
@for /F "eol=| tokens=1* delims=_" %%A in ('dir /B /A-D-H "%UserProfile%\Documents\NOTEPAD Coding\File Transfer Coding\Files\*_????-??-??_*.pdf" 2^>nul') do @for /D %%C in ("%UserProfile%\Documents\NOTEPAD Coding\File Transfer Coding\Transfer\%%A_*") do @move /Y "%UserProfile%\Documents\NOTEPAD Coding\File Transfer Coding\Files\%%A_%%B" "%%C\"
WellНеоптимизированная версия также может быть записана в виде еще более длинной отдельной командной строки:
@for /F "eol=| delims=" %%A in ('dir /B /A-D-H "%UserProfile%\Documents\NOTEPAD Coding\File Transfer Coding\Files\*_????-??-??_*.pdf" 2^>nul') do @for /F "eol=| tokens=1 delims=_" %%B in ("%%~nA") do @for /D %%C in ("%UserProfile%\Documents\NOTEPAD Coding\File Transfer Coding\Transfer\%%B_*") do @move /Y "%UserProfile%\Documents\NOTEPAD Coding\File Transfer Coding\Files\%%A" "%%C\"
Чтобы понять используемые команды и их работу, откройте окно командной строки, выполните там следующие команды и полностью прочитайтевсе страницы справки отображаются для каждой команды очень тщательно.
dir /?
echo /?
endlocal /?
for /?
move /?
set /?
setlocal /?