Прежде всего, вам нужно будет сохранить %1
в переменной, затем вы сможете выполнять замены.
По сути, синтаксис для замены таков:
%<i>variable</i>:<i>str1</i>=<i>str2</i>%
, что означает: 'заменить каждые str1
в variable
на str2
' .
В вашем случае str1
и str2
являются параметрами, а не литеральными строками. Используя приведенный выше шаблон напрямую, вы можете получить следующее выражение:
%variable:%3=%4%
.
Но это может запутать синтаксический анализатор, так как он не будет знать, что %3
и %4
должны оцениваться в первую очередь. Фактически, он сначала попытается оценить %variable:%
(и потерпит неудачу).
Одним из решений в этом случае может быть использование метода, называемого 'отложенная' отложенная оценка . По сути, вы передаете команду, в которой вы оцениваете переменную, команде CALL. Преобразование исходной команды в ее «версию CALL» выглядит так:
ECHO %var%
==> CALL ECHO %%var%%
.
Обратите внимание на двойные %
с. Во время анализа они оцениваются как единичные %
с. Полученная команда будет снова проанализирована CALL, и конечный эффект будет таким же, как и в случае исходной команды, ECHO %var%
.
Так что она работает так же, как исходная команда (что хорошо), и здесь мы получаем более позднее время оценки , я имею в виду окончательную оценку, когда переменная фактически заменяется на его ценность. Зная об этом эффекте, мы можем построить наше выражение таким образом, чтобы сначала вычислялись %3
и %4
, а затем все полученное выражение. Конкретно так:
%%variable:%3=%4%%
После первого разбора это выражение станет примерно таким:
%variable:x=y%
Это будет проанализировано снова, и на выходе будет измененное содержимое variable
.
Для лучшей иллюстрации вот простой рабочий пример:
SET "output=%1"
CALL SET output=%%output:%3=%4%%
ECHO %output%
UPDATE
Есть еще один способ сделать то же самое, о котором я, вероятно, должен был упомянуть первым.
Командная оболочка Windows поддерживает правильное отложенное расширение. Он проще в использовании, но имеет некоторые оговорки.
Во-первых, как его использовать. Синтаксис для отложенного расширения - !var!
вместо %var%
для немедленного расширения (который остается действительным и может использоваться вместе с синтаксисом отложенного расширения).
Возможно, !var!
не будет работать в вашем скрипте, пока вы не включите синтаксис командой:
SETLOCAL EnableDelayedExpansion
Команда ENDLOCAL
закрывает блок, в котором синтаксис отложенного расширения является действительным и интерпретируется командной оболочкой.
Приведенный выше пример сценария можно переписать так:
SET "output=%1"
SETLOCAL EnableDelayedExpansion
SET output=!output:%3=%4!
ECHO !output!
ENDLOCAL
Так как это работает в случае команды SET output=!output:%3=%4!
:
%3
и %4
оцениваются немедленно, т. Е. Во время разбора - они заменяются на x
и y
соответственно;
команда становится такой: SET output=!output:x=y!
;
команда собирается выполнить - вычисляется выражение !
(x
с заменены на y
с);
команда выполнена - переменная output
изменена.
Теперь о предостережениях. Первое, что нужно помнить, это то, что !
становится частью синтаксиса и используется и интерпретируется всякий раз, когда встречается. Поэтому вам нужно избегать его там, где вы хотите использовать его как литерал (например, ^!
).
Другим предупреждением является основной эффект блока SETLOCAL / ENDLOCAL. Дело в том, что все изменения переменных среды в таком блоке, ну, локально. При выходе из блока (после выполнения ENDLOCAL
) переменная устанавливается в значение, которое она имела до его ввода (до выполнения SETLOCAL
). Для вас это означает, что измененное значение output
будет действительным только в пределах блока SETLOCAL
, который вы должны были инициировать для использования в первую очередь отложенного расширения. Возможно, это не будет проблемой в вашем конкретном случае, если вам просто нужно изменить значение и затем использовать его сразу, но вам, вероятно, придется запомнить его на будущее.
Примечание. Согласно комментарию jeb , вы можете сохранить измененное значение и оставить блок SETLOCAL, используя этот трюк:
ENDLOCAL & SET "output=%output%"
Оператор &
просто разделяет команды, когда они находятся в одной строке. Они выполняются один за другим, в том же порядке, в котором они указаны. Дело в том, что к моменту синтаксического анализа строки блок SETLOCAL еще не был оставлен, поэтому %output%
оценивает измененное значение, которое все еще действует. Но присвоение фактически выполняется после ENDLOCAL
, т.е. после выхода из блока. Таким образом, вы эффективно сохраняете измененное значение после выхода из блока, тем самым сохраняя изменения. (Спасибо, Джеб !)
Дополнительная информация:
При отложенном расширении:
При замене подстроки: