Какой синтаксис будет проверять, определено ли имя переменной, содержащее пробелы?
имена пользовательских переменных среды Windows могут содержать любой символ, кроме =
.
специальные символы могут быть включены, избегая их. Более простой метод - просто заключить все выражение набора в кавычки. Например:
set "A weird & "complex" variable=My value"
set A weird ^& "complex" variable=My value
оба выражения дают одинаковый результат. Имя переменной A weird & "complex" variable
и значение My value
конструкция IF DEFINED используется для проверки переменная определена. Цитаты не работают для этого теста, специальные символы в имени (включая кавычки), должны быть экранированы.
set "A&B=value"
if defined A^&B echo This works
if defined "A&B" echo This does not work
вышеприведенный экранированный тест работает просто отлично. Цитируемый тест не работает
но как я могу проверить, существует ли переменная, содержащая пробелы?
set "A B=value"
if defined A^ B echo this does not work!
кажется, что выше должно работать, но это не так!
Я ищу ответ, который не включает в себя расширение переменной с помощью %A B% или !Б!
4 ответов
интересный вопрос (мне нравится этот синтаксис базовых вопросов).
очевидно, вы знаете, как проверить его с задержкой расширения, а также для-parameters работает.
@echo off
setlocal
set "AAA BBB=value"
set ""AAA BBB"="
set "AAA="
for %%a in ("AAA BBB") do if defined %%~a echo FOR: This works
setlocal EnableDelayedExpansion
set "varname=AAA BBB"
if defined !varname! echo Delayed: This works
if defined %varname% ( echo percent: Never comes here
) ELSE ( echo percent: Never comes here ? )
if defined AAA^ BBB ( echo escape1: Never comes here
) ELSE ( echo escape1: fails )
set AAA=Hello
if defined AAA^ BBB (
echo escape2: It only test for AAA the BBB will be "removed"
) ELSE ( echo escape2: fails )
set "space= "
if defined AAA!space!BBB echo inject space: This works
if defined "AAA BBB" (echo Quote1: Never comes here
) ELSE ( echo Quote1: Fails )
set ""AAA BBB"=value"
if defined "AAA BBB" echo Quote2: This works, it checks for "AAA BBB" with quotes
у меня такое, в escape2 пример парсер сначала разделил строку на токены таким образом:<if> <defined> <AAA BBB> <echo ....
Но во время исполнения если определено это пересканировать <AAA BBB>
токен, поэтому он получает только AAA
.
Ты не можешь сделать второй побег. как AAA^^^ BBB
как это только ищет переменную с именем AAA^
Я не вижу решения без задержки/для, так как выход из пространства всегда терпит неудачу.
EDIT: его также можно решить с помощью SET <varname>
Решение ijprest использует команду SET для тестирования переменной без необходимости экранирования varname.
Но он также показывает интересное поведение с пробелами внутри и в конце varname.
кажется следуйте этим правилам:SET varname
ищет все переменные, начинающиеся с varname, но сначала удаляет все символы после последнего символа пробела varname, и удаляет все ведущие пробелы.
Таким образом, вы не можете искать переменные, начинающиеся с пространства (но также немного сложно создать такое имя varname).
то же самое поведение также активно, если переменное имя заключено в кавычки, но затем существует еще одно правило.
Сначала удалите все символы после последней цитаты, Если есть хотя бы две цитаты.
Используйте текст внутри кавычек и используйте"пробел" -правило.
образец.
set " abc def ghi" junk junk
*** 1. removes the junk
set " abc def ghi"
*** 2. removes the quotes
set abc def ghi
*** 3. removes all after the last space, and the trailing spaces
set abc def
*** Search all variables beginning with abc def
Я тоже люблю такого рода вопрос! :)
вот еще одно возможное решение, которое я придумал... использование SET для проверки существования и использование результата ERRORLEVEL:
set "A B=foo"
set A B >nul 2>nul&& echo 1. This works
set "A B ">nul 2>nul&& echo 2. This works
set "A weird & "complex" variable=foo"
set A weird ^& "complex" variable >nul 2>nul&& echo 3. This works
set "A weird & "complex" variable ">nul 2>nul&& echo 4. This works
обратите внимание, что это работает, только если ваши переменные уникальный в том смысле, что ни одно имя переменной не является префиксом другого. В противном случае вы рискуете ложными срабатываниями, так как поведение SET по умолчанию-показать все переменные, начинающиеся с передаваемого параметра. Если бы это было возможно ... в случае, вы можете отфильтровать результаты с помощью findstr:
set "A B="
set "A B C=foo"
set "A B ">nul 2>nul&& echo 5. Failed (false positive)
set "A B "|findstr /B /L /C:"A B=" >nul||echo 6. This works (no false positive)
и один конечное пространство после имени переменной, по-видимому, требуется. Без него SET часто неправильно анализирует входные данные. Странно, если вы добавляете дополнительное пространство между "2>nul" и " & & "в случае #3 он перестает работать (если вы не удалите пространство перед ">nul")... странный.
другой способ-переназначить его на другую переменную (без пробелов) и проверить это. Смотрите здесь:
rem Prepare ONLY variable 'a b'
set "a b=123"
echo [a b]=%a b%
rem This will ouput: [a b] is defined
set var=%a b%
if defined var (
echo [a b] is defined
) else (
echo [a b] is not defined
)
rem This will output: [c d] is not defined
set var=%c d%
if defined var (
echo [c d] is defined
) else (
echo [c d] is not defined
)
Я делаю это, определяя флаг как TRUE, если это необходимо...
rem /* sample code */
set VAR_SET=
if <some condition> set VAR_SET=TRUE&set VAR=this data has spaces
rem /* test for VAR_SET using 'if defined' */
if defined VAR_SET (
rem /* do something with the other data in the variable %VAR% */
)
rem /* clear the flag */
set VAR_SET=