Экранирование скобок в скобках для командного файла

Вот что я пытаюсь сделать:

(
@echo This is some code that is
@echo Important to echo exactly as-is
@echo Even if I use parenthesis
@echo for something (like this)
)|clip

Итак, скопировав это в буфер обмена. Я пробовал следующее:

(
@echo This is some code that is
@echo Important to echo exactly as-is
@echo Even if I use parenthesis
@echo for something ^(like this^)
)|clip

Но это, кажется, влияет на мои WANTED скобки, потому что я получаю ошибку. Чтобы проверить это, я просто сделал:

(
@echo This is some code that is
@echo Important to echo exactly as-is
@echo Even if I use parenthesis
@echo for something ^(like this^)
FFF
)|clip

Привет! Это почти работает, текст копируется полностью до "s" в "this". Он не копирует последние скобки, или, очевидно, F. Есть идеи?

4 ответа

Решение

Очевидно, что вам нужно три кареты там:-)

(
@echo This is some code that is
@echo Important to echo exactly as-is
@echo Even if I use parenthesis
@echo for something (like this^^^)
)|clip

Зачем? Это немного сложно...

Сначала парсер анализирует блок и выходит из части this^^^) в this^), скобка была здесь исключена в первый раз.

Но так как вы использовали канал, весь блок будет переведен и перенесен в новый экземпляр cmd.exe.
C:\Windows\system32\cmd.exe /S /D /c" ( @ echo This is some code is ... & @ echo for something (like this^) )"

И в новом случае необходимо снова избежать закрывающей скобки.
Это все!

А для получения дополнительной информации вы можете прочитать аналогичный вопрос
SO: почему отложенное расширение завершается неудачно, когда внутри конвейерного блока кода

Если вас смущает количество карет, помните, что оно всегда равно 2 минус 1. Кроме того, помните, что в первый раз вы добавляете 2, второй раз 4, третий раз 8, ...

Например, (проверено на XP)

(
for /f "tokens=* delims=" %%S in (
'echo X^^^^^^^^^^^^^^^& ^^^^^^^^^^^^^^^| ^^^| find " "'
) do @echo %%S
) | find "X"

Оператор echo обычно читается первым, когда DOS анализирует пакетный файл (1), во-вторых, потому что это внутренняя команда по конвейеру (кажется, что DOS хочет программы в каналах, а внутренние команды не являются программами) (3), в-третьих, потому что он находится в список слов, управляемый командой 'for / f' (см. для /?) (7), и четвертый раз по причинам, уже указанным в этой теме (15).

Я также могу отметить, что лично я считаю небрежным кодирование, позволяющее избежать правильного экранирования горячих символов только из-за того, что DOS игнорирует пропущенное экранирование в данном конкретном случае. Поэтому, если бы я хотел повторить буквальную пару скобок в приведенном выше примере, я бы дал каждые 15 каретов, даже если открывающая скобка не нужна. Тогда любой, кто читает мой код, не должен удивляться, почему одна скобка заключена в кавычки, а другая - нет. И как изменить цитату под модификацией кода.

Мое решение, когда мне нужно использовать закрывающую скобку в моем инкапсулированном эхо, состоит в создании переменной с именем%endPar% в начале моего сценария, что-то вроде этого:

@set "endPar=)"
@echo This is some code that is>tmp
@echo Important to echo exactly as-is>>tmp
@echo Even if I use parenthesis>>tmp
@echo for something (like this%endPar%>>tmp
@type tmp|clip
@del tmp

Я немного изменил его и дважды протестировал.

Код просто выводит эхо-файл в файл с именем tmp, затем вы передаете содержимое файла в клип, и он готов для вставки в любое место.

Тройная каретка не работает во всех ситуациях. возьмите следующее:

IF EXIST file.txt (
ECHO ...OK
) ELSE (
ECHO TEST THIS: (SOME WORDING! ^^^)   > file.txt
)

содержимое файла file.txt:

TEST THIS: (SOME WORDING! ^)
Другие вопросы по тегам