Подтвердить что ты не робот

Сбой группового символа

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

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

При этом регулярное выражение, которое я действительно хочу,

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

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

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

4b9b3361

Ответ 1

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

TLDR

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

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

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

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

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

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

  • ^
  • &
  • <
  • >
  • |

Пример: echo a ^> b для печати a > b на экране

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

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

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

  • ,
  • ;
  • =
  • (
  • )

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

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

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

"""

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

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

Также

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

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

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

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

Ответ 2

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

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

:: Will work:
@echo Syntax: MyCommand ^> [file]

Ответ 3

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

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

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

EDIT: использование немодифицированных строк с пакетом

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

@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

Ответ 4

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