开发者

batch echo pipe symbol causing unexpected behaviour

I have a variable in my b开发者_如何学Goatch file and it contains the pipe symbol (this one: |) so when I echo the variable I get an error about a unrecognized internal/external command.

I need a way to either get it to echo it correctly or better yet remove everything after and including the | symbol as well as any extra spaces before it.


There are several special characters that generally must be escaped when used in Windows batch files. Here is a partial list: < > & | ^ %

The escape character is ^. So to get a literal |, you should do this:

echo ^|

When the special character is in a variable, it becomes a bit harder. But if you use special syntax, you can replace characters in a variable like this:

set X=A^|B

REM replace pipe character with underscore
set Y=%X:|=_%

echo %Y%
REM prints "A_B"


You must escape the | character before you print the var. The following prints a|b

@echo off

set x=a^|b
echo %x:|=^|%


The question did not specify the OS. For unix:

escape it

echo \|

or wrap in quotes

echo "|"


Old question, but there is one unmentioned solution, much easier to use:
Delayed Expansion

Using delayed expansion has the advantage, that any content can be used without modifications, there aren't any problematic characters at all.

set "test=A|B&C,D"E^<F^>G"
setlocal EnableDelayedExpansion
echo !test!

set test       --- Works, but shows also: "test=..."
echo %test% --- This one fails


set X=%0^|callset.bat
set Y=%X:|=_%
echo %Y%
echo %X% _ %Y%
REM activate callset | more

REM and you should have infinite pipe. Break CTRL+C twice Ctrl Break REM prints "The process tried to write to a nonexistent pipe."


Henrik's answer works fine if you simply want to echo the contents of a variable to the screen, but if you want to pipe a value containing a pipe symbol into another program (as I did) you need to add more carets (^):

Echo bare text containing a pipe (|):

echo Hello ^| world

Set-and-echo variable containing a pipe (|):

set txt=Hello ^| world
echo %txt:|=^|%

Echo bare text containing a pipe (|) into another program:

echo Hello ^^^| world | hexdump

produces:

000000   48 65 6c 6c 6f 20 7c 20 - 77 6f 72 6c 64 20 0a     Hello | world .

Set-and-echo variable containing a pipe (|) into another program:

set txt=Hello ^| world
echo %txt:|=^^^|% | hexdump

produces:

000000   48 65 6c 6c 6f 20 7c 20 - 77 6f 72 6c 64 20 0a     Hello | world .

(hexdump is just a utility I have to dump stdin in hex and ASCII).

The reason three carets (^^^) are needed (as I think I understand it) is because CMD essentially parses the command-line twice: once to identify that it contains an un-escaped pipe (the | hexdump bit); then each part gets processed a second time as it goes to execute them.

The first pass turns echo Hello ^^^| world into echo ^| world (read the middle bit as ^^ followed by ^|: an escaped caret and an escaped pipe). When it is processed the second time – while executing the pipeline – the "surviving" caret protects the pipe symbol so that Hello | world is fed into the next command.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜