Игнорировать знак процента в пакетном файле
У меня есть пакетный файл, который перемещает файлы из одной папки в другую. Пакетный файл генерируется другим процессом.
Некоторые из файлов, которые мне нужно переместить, содержат в них строку "%20":
move /y "\\myserver\myfolder\file%20name.txt" "\\myserver\otherfolder"
Это не удается, поскольку он пытается найти файл с именем:
\\myserver\myfolder\file0name.txt
Можно ли игнорировать %
? Я не могу изменить созданный файл, чтобы избежать этого, например, путем удвоения процентных знаков (%%
), экранирования с помощью /
или ^
(каретки) и т.д.
Ответы
Ответ 1
Вы можете использовать каретку (^) чтобы избежать знака процента.
Причина %2
исчезает, так как командный файл заменяет второй переданный аргумент, и у вас, похоже, нет второго аргумента. Один из способов обойти это - попробовать на самом деле foo.bat ^%1 ^%2...
, чтобы при встрече %2
в команде он был заменен буквальным %2
.
Ответ 2
В этом случае вам нужно использовать %%
. Обычно используется ^
(карет), но для знаков %
вам нужно удвоить.
В случае %%1
или %%i
или echo.%%~dp1
, потому что %
указывает ввод либо из команды, либо из переменной (когда она окружена %
; %variable%
)
Чтобы выполнить то, что вам нужно:
move /y "\\myserver\myfolder\file%%20name.txt" "\\myserver\otherfolder"
Надеюсь, это поможет!
Ответ 3
В пакетных файлах знак процента может быть "экранирован" с помощью знака с двойным процентом (%%).
Таким образом, в командной строке будет использоваться один знак процента. от http://www.robvanderwoude.com/escapechars.php
Ответ 4
Заголовок вопроса очень общий, что неизбежно привлекает многих читателей, ищущих общее решение.
Напротив, проблема OP очень специфична: нужно иметь дело с автоматически сгенерированным пакетным файлом, который плохо сформирован: знаки %
в нем не экранируются должным образом.
Принимаемый ответ дает умное решение конкретной и экзотической проблемы, но неизбежно создает путаницу в отношении общего вопроса.
Если мы сосредоточимся на общем вопросе:
-
К сожалению, интерпретатор команд Windows cmd.exe
работает по-разному в зависимости от того, указана ли строка в командной строке и внутри пакетного файла:
- Насколько мне известно, синтаксис не содержит синтаксиса
%
-escaping, который будет работать как в командной строке, так и в пакетных файлах.
-
Внутри пакетного файла:
- Используйте
%%
для создания литерала %
, внутри строки с двойными кавычками или; например.:
echo %%USERNAME%%
приводит к буквальному %USERNAME%
, а не к значению переменной USERNAME
.
-
В командной строке (интерактивная командная строка в окне консоли, которая по-прежнему ошибочно называется "подсказкой DOS" ) и при вызове команды оболочки из другой программы strong > (например, используя os.system()
в Python):
- Вы не можете напрямую скрыться
%
в командной строке, но вы можете решить проблему:
-
Внутри неуказанной строки вы можете использовать %^
вместо открытия %
ссылки на переменные, чтобы эффективно подавлять ее расширение; например.:
echo %^USERNAME%
приводит к буквальному %USERNAME%
, а не к значению переменной USERNAME
.
Технически вы можете поместить ^
в любом месте имени переменной, если оно не находится рядом с другим ^
, но я предлагаю принять это соглашение.
- Обратите внимание, что этот подход не работает в строках с двойными кавычками, где
^
не имеет особого значения и сохраняется как-есть.
-
Совет шапки jeb. Обратите внимание, как ^
, который обычно является escape-символом в некотируемом строки, здесь не используется (^
может выходить только символы, отличные от %
); вместо этого он используется для "разрушения" имени переменной для предотвращения расширения; в деталях это работает следующим образом:
-
^
ускользает от самого следующего символа, нужно ли экранировать этот символ или нет. Чистый эффект заключается в том, что такие экземпляры ^
в конечном итоге удаляются из некотируемых строк.
-
Однако в отношении синтаксического анализа ^
эффективно изменяет имя переменной, чтобы включить ^
, а в командной строке ссылка на undefined или пустую переменную сохраняется как (в отличие от внутри пакетных файлов, где он расширяется до пустой строки).
В нашем примере %^USERNAME%
интерпретатор ищет переменную с именем ^USERNAME
, которая обычно не существует, поэтому ссылка на переменную сохраняется как есть, что в сочетании с удалением ^
приводит к литералу %USERNAME%
.
- Незначительная оговорка:
^
на самом деле является юридическим символом в именах переменных (см. пример jeb в комментариях); если имя переменной начинается с ^
, просто поместите "подрывную" ^
в другое место в имени переменной, если она не находится непосредственно рядом с другим ^
(так как это приведет к появлению ^
результирующая строка).
Если ваша переменная имеет имя, например ^b^
, вам не повезло.
-
Обратите внимание, что экземпляры %
, которые не являются частью того, что выглядит как ссылка на переменную, рассматриваются как литералы в командной строке, независимо от того, являются ли они частью строки без кавычек или с двойными кавычками; например, echo 100%
дает 100%
, а echo "100%"
дает "100%"
.
Как указано, трюк "^
disrupter" не работает должным образом в строках с двойными кавычками, поскольку сохраняется ^
.
Ответ 5
Я думаю, что у меня есть частичное решение. Если вы только хотите перенести файлы со строкой "%20" в их имени и не ищете более широкое решение, вы можете сделать второй командный файл первым, а %%2 - вторым параметром. Таким образом, когда ваша программа пытается получить второй параметр, когда он попадает в% 2 в текстовое имя, он заменит% 2 экранированным% 2, оставив имя файла без изменений.
Надеюсь, что это сработает!