система не может найти путь, указанный при запуске командного файла - PullRequest
0 голосов
/ 11 мая 2018

Я пытаюсь переместить файлы после сортировки файлов из одной папки в другую, но всегда получаю это исключение «Системе не удается найти указанный путь»

Ниже приведен мойКод пакетной команды:

setlocal EnableDelayedExpansion
set destinationFolder=C:\Test_Actual_Queue
rem Create an array with filenames in right order
for /f "tokens=*" %%f in ('dir /b "C:\Test Print Queue\" ^| sort') do (
 echo %%f
 move %%f %destinationFolder%
)
pause

Я могу сортировать и отображать имена файлов в консоли, но когда я пытаюсь перейти в папку назначения, я получаю вышеупомянутое исключение.

Оба пути к папкам верны.

Я попытался отладить, и вот данные, которые я получаю в консоли:

C:\TestFoder>setlocal EnableDelayedExpansion

C:\TestFoder>set destinationFolder=C:\Test_Actual_Queue

C:\TestFoder>rem Create an array with filenames in right order

C:\TestFoder>for /F "tokens=*" %f in ('dir /b "C:\Test Print Queue\" | sort') do (
echo %f
 move %f C:\Test_Actual_Queue
)

C:\TestFoder>(
echo data1.Print_Job
 move data1.Print_Job C:\Test_Actual_Queue
)
data1.Print_Job
The system cannot find the file specified.

C:\TestFoder>(
echo data2.Print_Job
 move data2.Print_Job C:\Test_Actual_Queue
)
data2.Print_Job
The system cannot find the file specified.

что я здесь не так делаю?

С нетерпением ждем ваших решений.Заранее спасибо.

1 Ответ

0 голосов
/ 12 мая 2018

Команда DIR с аргументами /b и "C:\Test Print Queue\" выводит только имена всех не скрытых файлов и каталогов в указанном каталоге без пути. Текущий каталог при выполнении командного файла - C:\TestFoder, который отличается от C:\Test Print Queue. По этой причине команда MOVE не может найти файл / каталог для перемещения, сохраненный в C:\Test Print Queue, указанном без пути в текущем каталоге C:\TestFoder, и выводит сообщение об ошибке.

Команда DIR выведет имена файлов / папок с полным путем, если дополнительно опция /S используется для поиска также в подкаталогах.

Одно из решений - указать исходный путь также в командной строке MOVE :

@echo off
setlocal EnableExtensions DisableDelayedExpansion

set "SourceFolder=C:\Test Print Queue"
set "DestinationFolder=C:\Test_Actual_Queue"
set "CreatedFolder="

if not exist "%DestinationFolder%\" (
    md "%DestinationFolder%" 2>nul
    if not exist "%DestinationFolder%\" (
        echo Error: Failed to create folder "%DestinationFolder%"
        goto EndBatch
    )
    set "CreatedFolder=1"
)

for /F "eol=| delims=" %%I in ('dir /A-D-H /B /ON "%SourceFolder%\*" 2^>nul') do (
    echo Moving file "%SourceFolder%\%%I" ...
    move "%SourceFolder%\%%I" "%DestinationFolder%\"
)

if defined CreatedFolder rd "%DestinationFolder%" 2>nul

:EndBatch
endlocal
pause

Расширения команд явно включены, как требуется для for /F, хотя включены по умолчанию. Задержка раскрытия переменных среды явно отключена, поскольку она не требуется для этой задачи. Файлы с одним или несколькими восклицательными знаками в имени файла не могут быть успешно обработаны в цикле FOR , если отложенное расширение переменной среды включено явно, хотя не включено по умолчанию и здесь не требуется. Прочитайте этот ответ для получения подробной информации о командах SETLOCAL и ENDLOCAL .

Пакетный файл сначала создает папку назначения, если она еще не существует, с проверкой успешности создания папки.

Команда FOR выполняет командную строку

dir /A-D-H /B /ON "C:\Test Print Queue\*" 2>nul

в фоновом командном процессе, запущенном с cmd.exe /C.

Команда DIR Выходы

  • просто не скрытые файлы из-за /A-D-H, что означает, что все записи каталога не имеют каталог атрибутов или скрытый набор
  • в голом формате из-за /B, что означает только имя файла с расширением и без пути к файлу
  • отсортировано по имени из-за /ON
  • найдено в каталоге C:\Test Print Queue в соответствии с шаблоном подстановки * (любой файл).

Возможно, что исходный каталог вообще не существует или не содержит файлов, соответствующих критериям. Сообщение об ошибке, выводимое в этих случаях с помощью DIR , подавляется путем перенаправления его с дескриптора STDERR на устройство NUL .

Прочтите также статью Microsoft о Использование операторов перенаправления команд для объяснения 2>nul. Оператор перенаправления > должен быть экранирован с помощью символа вставки ^ в командной строке FOR , чтобы интерпретироваться как литеральный символ, когда интерпретатор команд Windows обрабатывает эту командную строку перед выполнением команды FOR , которая выполняет встроенную командную строку dir в отдельном командном процессе, запущенном в фоновом режиме.

FOR с опцией /F, как здесь используется, захватывает все, что написано для обработки STDOUT фонового командного процесса, а затем обрабатывает захваченный текст построчно.

Пустые строки игнорируются FOR , но DIR с использованными опциями вообще не выводит пустые строки.

Строки, начинающиеся с ;, также будут игнорироваться по умолчанию FOR . Имена файлов могут начинаться с точки с запятой. По этой причине опция eol=| используется для изменения символа конца строки с точки с запятой (по умолчанию) на вертикальную черту, которую имя файла не может содержать вообще.

FOR будет разбивать каждую строку на подстроки (токены), используя пробел по умолчанию и горизонтальную табуляцию, и назначать переменной цикла I только первую строку с пробелом / табуляцией. Такое поведение разделения здесь не требуется, и поэтому опция delims= используется для определения пустого списка разделителей, чтобы отключить разбиение строк и получить I всегда полное имя файла, даже если оно содержит один или несколько пробелов. tokens=* также можно использовать для получения всей строки (= имя файла), присвоенной I.

Для каждого файла, выводимого с помощью DIR с именем и расширением, но без пути, выводится имя файла и выполняется команда MOVE для перемещения файла в папку назначения без перезаписифайл с тем же именем в этой папке из-за опции /Y здесь не используется.

Наконец, пакетный файл удаляет папку назначения, если он был создан пакетным файлом, и если он все еще пуст, посколькунет файлов для перемещения вообще.

Другим решением было бы изменение текущего каталога на исходный каталог.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
cd /D "C:\Test Print Queue" || goto EndBatch

set "DestinationFolder=C:\Test_Actual_Queue"
set "CreatedFolder="

if not exist "%DestinationFolder%\" (
    md "%DestinationFolder%" 2>nul
    if not exist "%DestinationFolder%\" (
        echo Error: Failed to create folder "%DestinationFolder%"
        goto EndBatch
    )
    set "CreatedFolder=1"
)

for /F "eol=| delims=" %%I in ('dir /A-D-H /B /ON 2^>nul') do (
    echo Moving file "%%I" ...
    move "%%I" "%DestinationFolder%\"
)

if defined CreatedFolder rd "%DestinationFolder%" 2>nul

:EndBatch
endlocal
pause

Если команде CD не удалось изменить текущий каталог наИсходный каталог из-за его отсутствия выводит известное сообщение об ошибке:

Системе не удается найти указанный путь.

Затем пакетный файл переходит на метку EndBatch для восстановления предыдущей среды и прекращения выполнения пакетного файла до тех пор, пока пользователь не нажмет любую клавишу.

При успешном изменении текущего директораy пакетный файл продолжается, и с помощью команды ENDLOCAL начальный текущий каталог C:\TestFoder снова устанавливается в качестве текущего каталога для командного процесса, выполняющего пакетный файл.

Для понимания используемых команд и того, какони работают, открывают окно командной строки, выполняют там следующие команды и полностью читают все страницы справки, отображаемые для каждой команды.

  • cd /?
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • md /?
  • move /?
  • pause /?
  • rd /?
  • set /?
  • setlocal /?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...