2

As far as I know, I need to escape every escape characters when echoing them. The ^ method works fine for a few echoes. (which should be something like:)

@echo ^|
@echo ^> ^>^>

However, when there are a lot of characters to escape, the ^ method won't work anymore. So, my question is:

Are there any ways escape all special characters without "spamming" the caret?

2 Answers2

4

As mentioned by Mofi, you could use variables with delayed expansion to echo any content.

There are some more possible ways.

1) Disappearing quotes

for /F %%^" in ("""") do (
  echo %%~"Hello^you
  echo %%~"Line2 |&<>
)

This works as the %~" will quote the rest of the line, but after expansion it will disappear

2) When you want to echo multiple lines you should read about the different variants of heredoc

3) The MagicEcho can display any content without escaping or doubling percent signs like

%magicEcho% "^!%path%<>" ^%!%<> ^
Community
  • 1
  • 1
jeb
  • 78,592
  • 17
  • 171
  • 225
  • `for /l %%p in (1,1,100) do for /F %%^" in ("""") do ( echo %%~"Hello^you & echo %%~"Line2 |&<> )` does not work? –  Mar 15 '17 at 07:48
  • 1
    @SteveFest Put the second echo in a new line, as the `&` won't be parsed, but the second `%%~"` will leave the quoted context – jeb Mar 15 '17 at 08:28
3

Well, there is no need to escape redirection operators and other special characters listed in last paragraph in help output by running cmd /? in a command prompt window on last help page when the string to output is enclosed in double quotes.

But using " on line with ECHO command results in having also the double quote output.

There are several solutions.

The first one is assigning the string to output to an environment variable and output the value of the environment variable using delayed expansion.

@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "Line=pipe = | and percent sign = %% and exclamation mark ^!"
echo !Line!
set "Line=redirection operators: < and > and >>"
echo !Line!
endlocal

Or a little bit shorter, but not so good readable:

@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "Line=pipe = | and percent sign = %% and exclamation mark ^!" & echo !Line!
set "Line=redirection operators: < and > and >>" & echo !Line!
endlocal

Note: % and ! must be nevertheless escaped with another % and with ^ to be interpreted as literal character in string assigned to environment variable Line.

Another solution using a subroutine PrintLine:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
call :PrintLine "pipe = | and percent sign = %%%% and exclamation mark !"
call :PrintLine "redirection operators: < and > and >>"
endlocal
goto :EOF

:PrintLine
set "Line=%~1"
setlocal EnableDelayedExpansion
echo !Line!
endlocal
goto :EOF

The disadvantages of this solution are:

  1. A percent sign must be defined with 4 percent signs to be finally printed as literal character.
  2. It is slower because of usage of SETLOCAL and ENDLOCAL on printing each line.

Read this answer for details about the commands SETLOCAL and ENDLOCAL.

One more solution according to comment by JosefZ uses command FOR for an implicit delayed expansion:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
for %%I in (
    "pipe = | and percent sign = %% and exclamation mark !",
    "redirection operators: < and > and >>"
) do echo %%~I
endlocal

The lines to output are specified in a comma separated list of double quoted strings for being processed by FOR.

It has the big advantage that just the percent sign must be escaped with an additional percent sign on delayed expansion being disabled. But the string to output can't contain a double quote with exception of "" within string.

Thanks JosefZ for this contribution.

Other great solutions are provided by jeb in his answer.

Community
  • 1
  • 1
Mofi
  • 46,139
  • 17
  • 80
  • 143
  • `for %%G in ("|", "> \ ^", "> <<") do @echo %%~G` utilising _implicit_ delayed expansion of a `for` loop pilot variable `%%G`. – JosefZ Mar 15 '17 at 07:18
  • Since I'm too bored, I did some tests and found out `call` is twice slower than `set "a=|` –  Mar 15 '17 at 07:46
  • 2
    And `call` gets nasty with carets in the text, combined with exclamation marks it gets really funny – jeb Mar 15 '17 at 08:29