Игнорировать знак процента в пакетном файле
У меня есть пакетный файл, который перемещает файлы из одной папки в другую. Пакетный файл генерируется другим процессом.
Некоторые из файлов, которые мне нужно переместить, содержат строку "%20":
move /y "\\myserver\myfolder\file%20name.txt" "\\myserver\otherfolder"
Это не удается, так как он пытается найти файл с именем:
\\myserver\myfolder\file0name.txt
Есть ли способ игнорировать %
? Я не могу изменить сгенерированный файл, чтобы избежать этого, например, путем удвоения знака процента (%%
), убегая с /
или же ^
(карет) и т. д.
5 ответов
Вы должны быть в состоянии использовать каретку (^), чтобы избежать знака процента.
Примечание редактора: ссылка устарела; в любом случае: это %
Сам, что ускользает %
, но только в пакетных файлах, а не в командной строке; ^
никогда не убегает %
, но в командной строке его можно использовать косвенно, чтобы предотвратить расширение переменной, только в строках без кавычек.
Причина %2
исчезает то, что пакетный файл заменяет второй передаваемый аргумент, а у вас, похоже, нет второго аргумента. Один из способов обойти это было бы на самом деле попробовать foo.bat ^%1 ^%2...
так что когда %2
встречается в команде, фактически заменяется литералом %2
,
Вам нужно использовать %%
в этом случае. Обычно используя ^
(карет) будет работать, но для %
признаки вам нужно удвоить.
В случае %%1
или же %%i
или же echo.%%~dp1
, так как %
указывает ввод либо из команды, либо из переменной (когда окружен %
; %variable%
)
Чтобы достичь того, что вам нужно:
move /y "\\myserver\myfolder\file%%20name.txt" "\\myserver\otherfolder"
Надеюсь, это поможет!
Название вопроса очень общее, что неизбежно привлекает многих читателей, ищущих общее решение.
В отличие от этого, проблема OP является экзотической: необходимость иметь дело с автоматически сгенерированным пакетным файлом, который неправильно сформирован и не может быть изменен: %
знаки не избегают должным образом в нем.
Принятый ответ обеспечивает разумное решение конкретной - и экзотической - проблемы, но неизбежно создает путаницу в отношении общего вопроса.
Если мы сосредоточимся на общем вопросе:
Как вы используете %
как буквальный символ в командном файле / в командной строке?
Внутри командного файла всегда убегай
%
как%%
будь то в кавычках или нет; следующие урожаиMy %USERNAME% is jdoe
, например:echo My %%USERNAME%% is %USERNAME% echo "My %%USERNAME%% is %USERNAME%"
В командной строке (в интерактивном режиме) - а также при использовании вызывающих оболочку функций языков сценариев - поведение принципиально отличается от поведения внутри командных файлов: технически,
%
невозможно избежать этого, и нет единого обходного пути, которое работает во всех ситуациях:В строках без кавычек вы можете использовать
^
трюк "разрушитель имен": для простоты поместите^
перед каждым%
символ, но учтите, что хотя вы технически не спасаетесь%
таким образом (подробнее см. ниже); например, следующее снова дает что-то вродеMy %USERNAME% is jdoe
:echo My ^%USERNAME^% is %USERNAME%
В двойных кавычках нельзя убежать
%
на всех, но есть обходные пути:Вы можете использовать строки без кавычек, как указано выше, что затем требует от вас дополнительно
^
- избегать всех других метасимволов оболочки, что является громоздким; эти метасимволы:<space> & | < > "
В качестве альтернативы, если целевая программа поддерживает ее (должна работать с большинством двоичных исполняемых файлов, но не с пакетными файлами), вы можете представить
%
символы. как"%"
; например:echo "My "%"USERNAME"%" is %USERNAME%"
Из языков сценариев, если вы знаете, что вызываете двоичный исполняемый файл, вы можете избежать всей проблемы, отказавшись от вызывающих оболочку функций в пользу "безоболочечных" вариантов, таких как использование
execFileSync
вместоexecSync
в Node.js.
Необязательная справочная информация для командной строки (интерактивная):
Наконечник шляпы, чтобы jeb его за помощь в этом разделе.
В командной строке (в интерактивном режиме) %
технически не может быть вообще спасен; в то время как ^
как правило, cmd.exe
побег персонаж, это не относится к %
,
Как уже говорилось, не существует решения для строк в двойных кавычках, но есть обходные пути для строк без кавычек:
Причина, по которой " ^
"Разрушитель имен" (что-то вроде ^%USERNAME^%
) работает это:
Это "разрушает" имя переменной; то есть в приведенном выше примере
cmd.exe
ищет переменную с именемUSERNAME^
которого (надеюсь) не существует.В командной строке - в отличие от пакетных файлов - ссылки на неопределенные переменные сохраняются как есть.
Технически, один ^
внутри имени переменной - где угодно внутри нее, если она не рядом с другой ^
- достаточно, чтобы %USERNAME^%
например, было бы достаточно, но я предлагаю принять соглашение о методическом размещении ^
перед каждым %
для простоты, потому что это также работает для таких случаев, как up 20^%
где нарушение даже не является необходимым, но является мягким, поэтому вы можете применять его методично, без необходимости думать о специфике входной строки.
^
перед открытием %
, хотя и не обязательно, является добрым, потому что ^
экранирует следующий символ, независимо от того, нуждается ли он в экранировании - или, в этом случае, может быть экранирован - или нет. Чистый эффект заключается в том, что такой ^
экземпляры в конечном итоге удаляются из строк без кавычек.
В основном гипотетическая оговорка: ^
на самом деле является допустимым символом в именах переменных (см. пример jeb в комментариях); если имя вашей переменной заканчивается ^
Просто поместите "разрушительный" ^
где - то еще в имени переменной, если она не находится рядом с другой ^
(поскольку это вызвало бы ^
появляться в результирующей строке).
Тем не менее, в (очень маловероятном) случае, что ваша переменная имеет имя, такое как ^b^
, не повезло тебе.
В пакетных файлах знак процента может быть "экранирован" с помощью двойного знака процента ( %%). Таким образом, в командной строке будет использоваться один знак процента. с http://www.robvanderwoude.com/escapechars.php
Как "уйти" внутри командного файла с возможностью изменения файла ** Исходный вопрос касается сгенерированного файла, который не может быть изменен, но содержит такие строки, как:
move /y "\\myserver\myfolder\file%20name.txt" "\\myserver\otherfolder"
Частично это можно решить, вызвав сценарий с соответствующими аргументами (%1
,
%2
,...)
@echo off
set "per=%%"
call generated_file.bat %%per%%1 %%per%%2 %%per%%3 %%per%%4
Это просто устанавливает аргументы:
arg1="%1"
arg2="%2"
...
Как добавить буквальный знак процента в командную строку
mklement0 описывает проблему, заключающуюся в том, что избежать знака процента в командной строке сложно, а внутри кавычек это кажется невозможным.
Но, как всегда, ее можно решить с помощью небольшой хитрости.
for %Q in ("%") do echo "file%~Q20name.txt"
%Q
содержит
"%"
и
%~Q
расширяется только до
%
, независимо от котировок.
Или чтобы избежать
%~
использовать
for /F %Q in ("%") do echo "file%Q20name.txt"
Я думаю, что у меня работает частичное решение. Если вы хотите передать только те файлы, в имени которых содержится строка "%20", и не ищете более широкого решения, вы можете сделать второй вызов пакетного файла первым, указав %% 2 в качестве второго параметра. Таким образом, когда ваша программа пытается извлечь второй параметр, когда она достигает% 2 в текстовом имени, она заменит% 2 на экранированный% 2, оставив имя файла без изменений.
Надеюсь, это работает!