Пытаюсь записать вызывающий пакетный файл, но продолжаю получать ошибку «не удается найти»

#batch-file #path #cmd #wildcard

#пакетный файл #путь #cmd #подстановочный знак

Вопрос:

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

 set mmcIpath="C:"*"mmc-stable-win32MultiMCinstances"

call C:%mmcIpath%spc_we_replace_CED CEDU.bat
 

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

—ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ—

Я запускаю программу запуска Minecraft под названием MultiMC5; у нее есть функция, которая запускает команды, но по какой-то причине только одну команду. Поэтому я хотел, чтобы он вызывал пакетный файл для запуска нескольких команд.

Мой основной пакетный файл находится в «C:…MultiMCinstances «, но я хочу, чтобы программа могла его вызывать. Это невозможно, поскольку оно работает в подкаталоге с именем «CED (210 mods-)». Поэтому я поместил еще один пакет в подкаталог для вызова основного (я хотел сделать то же самое для второго подкаталога с именем «CEDU (300 mods-)»). Я получил эту ошибку: «Система не может найти указанный путь».. Это произошло, когда я установил путь.

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

Мой вопрос:

Совместима ли команда set с подстановочными знаками, и если да, то как мне заставить это работать?

Комментарии:

1. set устанавливает переменную в строку. * является допустимым символом в строке. Но вы не можете использовать путь с подстановочным знаком. Почему вы хотите использовать подстановочный знак?

2. Я хочу сделать это, чтобы я мог поместить каталог везде, где мне нужно, не меняя пакетный файл все время. Казалось, что раньше это работало с пакетным файлом, который имел точно такой же код (хотя по какой-то причине я не мог проверить, так как команда pause не работала).

3. Существует способ поиска каталога, но это может занять несколько минут. Это вариант для вас? Чем лучше вы можете определить, где находится этот каталог, тем быстрее будет поиск. (например: всегда ли он ниже%USERPROFILE%?)

4. Это так, хотя на других компьютерах я хочу запустить его с USB-накопителя (пытаясь использовать подстановочные знаки в именах дисков). Причина, по которой я использую цепочку пакетных файлов, заключается в том, что программа запускает команды внутри каталога, но я хочу сохранить свой основной пакет снаружи, поскольку он довольно большой (занимает много памяти, поскольку он должен исключать много файлов и делать другие вещи).). Итак, я попытался использовать меньший пакетный файл внутри каталога для его вызова, но, похоже, это не работает.

5. -извините, новичок в StackExchange — под «Это» я имел в виду, что он находится в%USERPROFILE% и находится в папке Documents (программа существует в нескольких «фиксированных» каталогах, иначе она не работала бы).

Ответ №1:

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

Вы можете получить диск с %~d0 помощью, путь с %~p0 и диск путь с %~dp0 . Посмотрите Пример ниже и запустите этот небольшой пакетный файл, хранящийся в нескольких разных каталогах:

 @echo off
echo Batch is stored on drive %~d0
echo in the directory %~p0
echo resulting in path %~dp0
 

Таким образом, вы можете использовать аргумент 0, на который ссылается %0, всегда содержащий имя пакетного файла с полным путем, используя синтаксис, описанный выше в справке о команде FOR , отображаемой при вводе for /? в окне командной строки, для вызова других пакетных файлов с путем, зависящим от пути основного пакетного файла.

Комментарии:

1. Хорошо … … единственная проблема в том, что мой основной пакетный файл находится в родительском каталоге (см. Комментарий выше — под сообщением выше)…

Ответ №2:

Теперь мы имеем здесь классическую проблему XY — нас спрашивают о решении, а не о основной проблеме.

Вот возможное решение:

 @ECHO OFF
SETLOCAL
set mmcIpath="C:"*"mmc-stable-win32MultiMCinstances"
set "mmcIpath=U:\.*\mmc-stable-win32\MultiMC\instances"
SET "targetbat=spc_we_replace.bat"

FOR /f "delims=" %%a IN (
  'dir /b/s /ad "%mmcIpath:~0,3%"^|findstr /e /i /r /c:"%mmcIpath%" '
  ) DO (
 IF EXIST "%%a%targetbat%" (
  ECHO CALL "%%a%targetbat%"
  ECHO GOTO nextstep
 )
)

:nextstep

GOTO :EOF
 

Я оставил исходную настройку mmcIpath на месте и заменил ее формой, соответствующей моей системе.

Подход заключается в выполнении dir/s/b/ad команды (каталог, базовый формат, с подкаталогами, только имена каталогов) и фильтрации ее с помощью findstr . Я выбрал переключатели /i (без учета регистра) /e (должны заканчиваться строкой) /r регулярное выражение /c: (ниже приведена одна строка для сопоставления).

Регулярное выражение создается в соответствии findstr с правилами — его необходимо удвоить, если оно должно использоваться как литерал; .* означает «любое количество любых символов»

Это должно предоставить список буквенных имен каталогов, которые проходят через фильтр. Найдите в найденном каталоге имя файла, call целевой файл, если он найден. Требуемые команды ВЫЗОВА редактируются только ECHO для целей тестирования. После того, как вы убедились, что команды верны, измените ECHO CALL на CALL фактическое выполнение файлов.

Ниже ECHO GOTO показано, что цикл может быть прерван после нахождения первого целевого файла, если это необходимо. Вы не указали, хотите ли вы запускать только первый или запускать все найденные целевые объекты.


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

 @ECHO OFF
SETLOCAL
SETLOCAL ENABLEDELAYEDEXPANSION
set "mmcIpath=mmc-stable-win32MultiMCinstances"
FOR /l %%a IN (1,1,4) DO MD u:%%a%mmcIpath% 2>nul
FOR /l %%a IN (2,2,4) DO COPY NUL u:%%a%mmcIpath%spc_we_replace.bat 2>NUL >nul
ENDLOCAL
ENDLOCAL


@ECHO OFF
SETLOCAL
set mmcIpath="C:"*"mmc-stable-win32MultiMCinstances"
set "mmcIpath=U:\.*\mmc-stable-win32\MultiMC\instances"
SET "targetbat=spc_we_replace.bat"

FOR /f "delims=" %%a IN (
  'dir /b/s /ad "%mmcIpath:~0,3%"^|findstr /e /i /r /c:"%mmcIpath%" '
  ) DO (
 IF EXIST "%%a%targetbat%" (
  ECHO CALL "%%a%targetbat%"
  ECHO GOTO nextstep
 )
)

:nextstep

GOTO :EOF
 

Обратите внимание, что первый раздел просто устанавливает u:1mmc-stable-win32MultiMCinstances u:4mmc-stable-win32MultiMCinstances , а затем создает фиктивный файл spc_we_replace.bat в u:2mmc-stable-win32MultiMCinstances и u:4mmc-stable-win32MultiMCinstances .

Строка, назначенная mmcIath во втором разделе, соответствует findstr правилам синтаксиса — каждый удваивается, .* означает «любое количество любого символа». Вам придется изменить эту строку в соответствии с вашей системой. Обратите внимание, что "%mmcIpath:~0,3%" безвозмездно принимает первые 3 символа из строки. В моем случае это было бы U: . YMMV

Комментарии:

1. -вздох — Моя проблема в том, что я хочу автоматически заменить некоторые файлы модов Minecraft в некоторых моих каталогах. У меня есть несколько файлов для замены, поэтому я попытался использовать программу (это средство запуска под названием MultiMC5) для этого. Однако он может выполнить только одну команду — не более. Поэтому я хотел, чтобы он вызывал основной пакет, поскольку у меня много экземпляров, поэтому я создал тот, который является универсальным для папок экземпляров. Но потом я понял, что программа работает только в каталоге экземпляра, а не в родительском (где находится файл). Итак, я попытался использовать короткую цепочку пакетных файлов, и это тоже не сработало.

2. Кроме того, я протестировал ваш, но он не сработал (получил другую ошибку «не удается найти указанный путь»). Должен ли я сам его настраивать?