z1lent
z1lent

Reputation: 147

Batch file function of |

What is the function of this symbol, "|" do in batch file (shift + )? Why is it that when I try to run the following code:

@echo off
echo ___________              __  .__                
echo \__    ___/___   _______/  |_|__| ____    ____  
echo   |    |_/ __ \ /  ___/\   __\  |/    \  / ___\  
echo   |    |\  ___/ \___ \  |  | |  |   |  \/ /_/  >
echo   |____| \___  >____  > |__| |__|___|  /\___  / 
echo              \/     \/               \//_____/   

or simply

echo |

the program just starts then exits instantly even if I put

pause

at the end


Thanks

Upvotes: 0

Views: 137

Answers (3)

dbenham
dbenham

Reputation: 130849

As others have said, the | is the pipe operator which takes the output of any command on the left and passes it as input to the command on the right. If you want to treat the character as a literal, then it must be escaped as ^| or quoted. But you don't want quotes in your output.

You also use the redirection operator > which requires escaping.

You might run into other characters that need to be escaped or quoted (sometimes referred to as "poison" characters):

            escape
character  sequence

   ^          ^^
   |          ^|
   <          ^<
   >          ^>
   &          ^&
   %          %%

If you script a command with an unquoted and unescaped | that is not a valid pipe operation, then it generates a fatal syntax error, and the script terminates immediately.

Your code can be fixed by escaping all the "poison" characters. But adding the ^ escape character makes the source code nearly unreadable:

@echo off
echo ___________              __  .__                 
echo \__    ___/___   _______/  ^|_^|__^| ____    ____   
echo   ^|    ^|_/ __ \ /  ___/\   __\  ^|/    \  / ___\  
echo   ^|    ^|\  ___/ \___ \  ^|  ^| ^|  ^|   ^|  \/ /_/  ^> 
echo   ^|____^| \___  ^>____  ^> ^|__^| ^|__^|___^|  /\___  /  
echo              \/     \/               \//_____/   

There are coding techniques that allow you to preserve the original appearance in the source code, and still get the desired output.

1) Simple FOR with quoted values

Limitations: output cannot contain ", *, or ?

for %%A in (
" ___________              __  .__                 "
" \__    ___/___   _______/  |_|__| ____    ____   "
"   |    |_/ __ \ /  ___/\   __\  |/    \  / ___\  "
"   |    |\  ___/ \___ \  |  | |  |   |  \/ /_/  > "
"   |____| \___  >____  > |__| |__|___|  /\___  /  "
"              \/     \/               \//_____/   "
) do echo %%~A

The ~ modifier in %%~A removes the enclosing quotes

2) labeled text combined with FOR /F with FINDSTR

Limitation: no output line can begin with :

@echo off

::: ___________              __  .__                
::: \__    ___/___   _______/  |_|__| ____    ____  
:::   |    |_/ __ \ /  ___/\   __\  |/    \  / ___\ 
:::   |    |\  ___/ \___ \  |  | |  |   |  \/ /_/  >
:::   |____| \___  >____  > |__| |__|___|  /\___  / 
:::              \/     \/               \//_____/  

for /f "delims=: tokens=*" %%A in ('findstr "^:::" "%~f0"') do @echo(%%A

I chose ::: as the message label because :: is often used as a comment.

The above works well, but it is not convenient if you want to specify multiple messages. This can be solved easily by being more creative with the label. A :print subroutine also is convenient

@echo off

::Testing: ___________              __  .__                
::Testing: \__    ___/___   _______/  |_|__| ____    ____  
::Testing:   |    |_/ __ \ /  ___/\   __\  |/    \  / ___\ 
::Testing:   |    |\  ___/ \___ \  |  | |  |   |  \/ /_/  >
::Testing:   |____| \___  >____  > |__| |__|___|  /\___  / 
::Testing:              \/     \/               \//_____/  
::Testing:

::Test: ___________              __  
::Test: \__    ___/___   _______/  |_
::Test:   |    |_/ __ \ /  ___/\   __\
::Test:   |    |\  ___/ \___ \  |  |
::Test:   |____| \___  >____  > |__|
::Test:              \/     \/      
::Test:

call :print Testing
call :print Test
exit /b    

:print  label
for /f "delims=: tokens=1*" %%A in ('findstr "^::%~1:" "%~f0"') do echo(%%B
exit /b

For even more flexability - check out How would I use some multi line ascii art as my characters for a counter? (batch).

In particular, my answer and Aacini's answer both give you options for printing nearly any string using a banner font of your choosing.

Upvotes: 5

Felipe Gutierrez
Felipe Gutierrez

Reputation: 535

the pipe "|" is to nest two commands. You get the output of the first command and nest is to the second command.

Upvotes: 0

Marc B
Marc B

Reputation: 360702

It's a "pipe" operator.

e.g.

commandA | commandB

takes the output of commandA and PIPES it as input to commandB. You'll have to escape the pipe character to make it be treated as a plaintext character, not a pipe:

echo ^|

Upvotes: 4

Related Questions