Пакетный персонаж убегает - PullRequest
35 голосов
/ 26 июля 2011

Я довольно опытный в написании Batch-скриптов для Windows, но даже после всех этих лет, как правильно экранировать персонажей, меня озадачивает.Это особенно сложно при попытке найти правильный способ избежать регулярного выражения для использования с sed.Есть ли инструмент, который может мне помочь?Возможно, что-то, что позволяет мне вставить «нормальную» строку, и оно выплевывает правильно экранированную версию этой строки?

Обновление: Я не хочу приводить пример, потому что я 'Я не ищу ответ о том, как избежать одной конкретной строки.Я также не ищу решение, которое будет работать для одного конкретного приложения.Я ищу инструмент, который поможет мне получить правильный синтаксис escape для каждой строки, которую мне нужно экранировать, независимо от того, какой инструмент использует его из командной строки.

То, что я действительно хочу получить регулярное выражение:

(^.*)(Form Product=")([^"]*") FormType="[^"]*" FormID="([0-9][0-9]*)".*$

Возьмите это истинное регулярное выражение (то есть неэкранированное до степени BATCH) и оберните его в некоторый синтаксис sed, например ssed "s@ --- Insert escaped regex here --- @http://psph/\1/\2@g" "%~1"и, наконец, избежать этого ... Опять же, есть ли инструмент, который может помочь в экранировании любой строки для использования в командной строке BATCH?

ps. Существует так много исключений из избегающего синтаксиса BATCH, что я даже соглашусь на хорошую шпаргалку.

Ответы [ 4 ]

46 голосов
/ 15 апреля 2013

Адаптировано с разрешения автора со страницы. Пакетные файлы - символы побега на Сайт сценариев Роба ван дер Вуде .

TLDR

Экранирование символов командного файла в Windows (и DOS) является сложным :

Так же, как и вселенная, если кто-нибудь когда-либо сделает полностьючтобы понять Batch, язык будет немедленно заменен бесконечно более странной и более сложной версией самого себя.Это, очевидно, случалось, по крайней мере, один раз раньше;)

Знак процента

% может быть экранирован как %% - "Может не всегда требоваться [чтобы бытьэкранированный] в строках в двойных кавычках, просто попробуйте "

Как правило, используйте каретку

Эти символы" не всегда требуются [для экранирования] в строках в двойных кавычках, но это не повредит ":

  • ^
  • &
  • <
  • >
  • |

' "требуется [для экранирования] только в FOR /F" субъекте "(то есть в скобках), , если не используется backq"

` "требуется [для экранирования] только в FOR /F" субъекте "(то есть в скобках), , если используется backq"

Эти символы "обязательны [для экранирования] только в FOR /F" субъекте "(то есть в скобках), даже в строках в двойных кавычках":

  • ,
  • ;
  • =
  • (
  • )

Восклицательные знаки двойного побега при использовании отложенного расширения переменной

! должны быть экранированы ^^!, когда активна задержка расширения переменной.

Двойные двойные кавычки в find Поиск шаблонов

"""

Использование обратной косой черты в findstr Шаблонах регулярных выражений

  • \
  • [
  • ]
  • "
  • .
  • *
  • ?

Также

Роб прокомментировал этот вопрос далее (по электронной почте):

Что касается ответа, я боюсь, что хаос еще хуже, чем понимает оригинальный плакат: требования к экранированию скобок также зависят от того, находится строка внутри блока кода или нет!

Я полагаю, что автоматизированный инструмент может простовставьте каретку перед каждым символом, затем удвойте все знаки процента - и все равно не получится, если строка будет заключена в двойные кавычки!

Мехкроме того, отдельные программы отвечают за синтаксический анализ своих аргументов командной строки, поэтому некоторые из экранирований, требуемых, например, для sed или ssed, могут быть связаны с конкретными программами, вызываемыми в пакетных сценариях.

6 голосов
/ 26 июля 2011

Экранирующим символом для пакета является символ каретки (^). Если вы хотите включить какой-либо из символов конвейера в ваш скрипт, вам нужно добавить префикс символа с помощью каретки:

:: Won't work:
@echo Syntax: MyCommand > [file]

:: Will work:
@echo Syntax: MyCommand ^> [file]
1 голос
/ 26 июля 2011

Вы можете просто использовать внешний файл в качестве входных данных для sed.

Или используя строки непосредственно в пакетном режиме, рекомендуется использовать отложенное расширение.

setlocal DisableDelayedExpansion
set "regEx=s/^#*$/""/g"
setlocal EnableDelayedExpansion
sed !regEx! file.txt

РЕДАКТИРОВАТЬ: Как использовать неизмененные строки сbatch

При этом findstr получает строку непосредственно из пакета и возвращает ее в переменную результата.
Таким образом, вы можете использовать sed-string как есть.

@echo off
setlocal
REM SedString1#(^.*)(Form Product=")([^"]*") FormType="[^"]*" FormID="([0-9][0-9]*)".*$

call :GetSEDString result SedString1
setLocal EnableDelayedExpansion
echo the sedString is !result!
sed !result!
goto :eof

:GetSEDString <resultVar> <searchName>
:: Search the own batch file for <searchName> in a line with "REM <searchName>#"
:: Return all after the "#" without any modification
setLocal DisableDelayedExpansion
for /f "usebackq tokens=* delims=" %%G in (`findstr /n /c:"REM %~2#" "%~f0"`) do (
    set "str=%%G"
)
setLocal EnableDelayedExpansion
set "str=!str:*#=!"

for /F "delims=" %%A in ("!str!") DO (
  endlocal
  endlocal
  set "%~1=%%A"
  goto :eof
)

goto :eof
0 голосов
/ 23 февраля 2018

Простым решением для сохранения всех аргументов командной строки является использование %*: он возвращает всю командную строку, начиная с первого аргумента командной строки (в Windows NT 4, %* также включает все начальные пробелы) и исключая любыеперенаправление вывода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...