Как переместить файлы из исходного каталога в каталог назначения с именем первой части имени файла? - PullRequest
0 голосов
/ 12 сентября 2018

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

Я пытаюсьперенести файлы PDF из определенного места в отдельные папки в другом месте.Каждое имя файла имеет формат RANSOM-NH_2018-08-07_5485A635.pdf и на основе RANSOM-NH_ пакетный файл должен передавать / перемещать PDF-файл в соответствующую папку с таким именем RANSOM-NH_Ransom INC.Таким образом, исходя из начальной части имени файла, файл должен быть перемещен в папку, имя которой начинается с первой части имени файла.

Некоторые примеры имен файлов и папок:

Имена файлов:

RANSOM-NH_2018-06-20_2018_5849.pdf
GREENWOOD_2018-07-02_66902.pdf
GLSCIENCES_2018-07-24_24811.pdf
CPI_2018-08-01_20039035.pdf
ALDR_2018-08-08_545477636.pdf
ACCQTRAX_2018-07-26_173845.pdf

Имена папок:

RANSOM-NH_Ransom INC
GREENWOOD_Greenwood Products, Inc
GLSCIENCES_GL Sciences, Inc
CPI_CPI International
ALDR_Sigma-Aldrich, Inc
ACCQTRAX_AccQtrax

У меня проблема в том, что написанный сценарий по-прежнему перемещает файл RANSOM-NH8_ в той же папке, чего не следует делать.

@ECHO OFF
SETLOCAL
SET "sourcedir=C:\Users\Alpha\Documents\NOTEPAD Coding\File Transfer Coding\Files"
SET "destdir=C:\Users\Alpha\Documents\NOTEPAD Coding\File Transfer Coding\Transfer"
FOR /f "delims=" %%a IN ('dir /b /a-d "%sourcedir%\*.pdf" ') DO (
    FOR /f "tokens=1 delims=_-" %%b IN ("%%a") DO (
        FOR /f "delims=" %%d IN ('dir /b /ad "%destdir%\*%%b*" ') DO (
            MOVE "%sourcedir%\%%a" "%destdir%\%%d\"
        )
    )
)
GOTO :EOF

1 Ответ

0 голосов
/ 12 сентября 2018

Попробуйте этот код командного файла:

@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 /?
...