1 (изменено: wisgest, 2012-09-25 12:08:24)

Тема: CMD/BAT: Запятая, кавычки в условии IF

Перенёс обсуждение запятой в условии IF из темы CMD/BAT: перевёртыш (зеркальное обращение текста) или Строковые ф-ции сюда.

Исходное сообщение:

По поводу строки в моём решении

if _!text:~%i%^,1!==_ …

у меня возник вопрос: почему понадобилось экранировать запятую?!

2

Re: CMD/BAT: Запятая, кавычки в условии IF

Rumata пишет:
wisgest пишет:

почему понадобилось экранировать запятую?

Возможно, поэтому:

cmd /?
...
The special characters that require quotes are:
     <space>
     &()[]{}^=;!'+,`~

3

Re: CMD/BAT: Запятая, кавычки в условии IF

Rumata пишет:

Возможно, поэтому:

cmd /?

Специальные символы, которые требуют обязательного заключения в кавычки:
     <пробел>
     &()[]{}^=;!'+,`~

Я не совсем понимаю, к чему относится этот последний абзац из встроенной справки CMD.EXE (возможно, он — следствие некоторой небрежности):
в одних случаях одни из перечисленных симолов требуют заключения в кавычки или экранирования, чтобы не восприниматься как специальные, а другие не требуют,
а в других случаях — третие и четвёртые (т.е. другие по отношению к другим ),
я что-то не припоминаю таких случаев для квадратных и фигурных скобок, да и для плюса в большинстве случаев этого не требуется,
с другой стороны, в этом списке нет символов перенаправления…


Но, по-моему, я нашёл источник ошибки: CMD.EXE воспринимает запятую и точку с запятой как такие же разделители, как и пробел, а попытка использовать незаковыченый пробел в операнде условия IF приводит к непредвиденному завершению операнда.
С другой стороны, по этой же причине, оказывается, не являются ошибочными такие выражения:

if 1==1,echo TRUE
if,1;equ,1;echo TRUE

(Но с третьей стороны, при использовании в условиях незаковыченных переменных окружения без отложенного раскрытия, например

if -%var:~0,1%==-/ (echo TRUE) else echo FALSE

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

4

Re: CMD/BAT: Запятая, кавычки в условии IF

Аскет пишет:
wisgest пишет:

По поводу строки в моём решении

if _!text:~%i%^,1!==_ …

у меня возник вопрос: почему понадобилось экранировать запятую?!

Ну, в любом случае Вам, как автору решения (во всяком случае), должно быть виднее.
И всё же, отвечая на вопрос "почему понадобилось экранировать запятую?!", скажу так: я бы заключил в кавычки.

"!text:~%i%,1!"==""

ИБО:

Справочник по командной строке пишет:

If
строка1==строка2
Условие выполняется, если строки строка1 и строка2 совпадают. Строки могут быть заданы явно или могут быть пакетными переменными (например, %1). Явно заданные строки нет необходимости заключать в кавычки.

Т.е. НЕявно заданные строки (переменные) необходимо заключать в кавычки.
Всё логично же...

5 (изменено: wisgest, 2012-09-25 12:27:19)

Re: CMD/BAT: Запятая, кавычки в условии IF

Аскет, задавая вопрос ответа я не знал, ошибка была устранена наугад,
её причину сразу не мог понять (первой мыслью было существование в командных файлах опрации «запятая» как в Си-подобных языках).

О решении с кавычками я знал, но мне было интересно обойтись без них;
с кавычками могут быть свои трудности…

Аскет пишет:

Всё логично же...

А по-моему, не очень.
Не следует безоговорочно доверять справке: иногда в ней встречаются ошибки и часто — упрощения и приблизительности.

Во-первых (в-нулевых), случай, когда строки заданы явно, — надуман: нет пользы задавть оба операнда явно, а если уж взять в кавычки один, то надо и второй.

Во-вторых, из сказанного вовсе формально не следует твое умозаключение, это лишь «добрый совет» (не всегда такой уж и добрый…). Более того, с правильной точки зрения операнд не заключается в кавычки, а кавычки становятся частью операнда (

if a=="a" (echo TRUE) else echo FALSE

возвратит «FALSE»)
и могут быть не только внешними, но и находится внутри операндов при условии сохранения чётности и того, что пробельные символы, к которым во встроенных командах CMD.EXE приравнены запятые и точки с запятой, попадают между кавычек так, что операнды не распадаются на части, например

set A=a" b "c
if %A%==%A% echo TRUE& rem     Условие истинно
if "%A%"=="%A%" echo TRUE& rem Синтаксическая ошибка

Правда, при использовании отложенного раскрытия переменных команда, подобная последней , сработает, т.к., в этом случае вначале проверяется синтаксис команды, а уж затем в неё подставляется значение переменной, так что в этом случае совет использовать кавычки и можно считать добрым (хотя, опять же, всё зависит от обоих операндов).

6 (изменено: wisgest, 2012-11-21 03:34:24)

Re: CMD/BAT: Запятая, кавычки в условии IF

wisgest пишет:

CMD.EXE воспринимает запятую и точку с запятой как такие же разделители, как и пробел…

…пробельные символы, к которым во встроенных командах CMD.EXE приравнены запятые и точки с запятой…

Обнаружил, что подобным образом почти всегда воспринимается и знак равенства.

Хотя в этом случае всё-таки есть исключения, мне пока вспомнились лишь три:
• команда SET: попытка вставить знак равенства перед именем переменной — синтаксическая ошибка, также как и его отсутствие после имени изменяет обработку команды, но перед самой командой — пожалуйста;
• в условие команды IF: удвоенный — оператор сравнения, как ведёт себя одиночный — не вполне понимаю;
• выражение с заменой подстроки переменной окружения (%VAR:substr1=substr2%).