Unix has a nifty feature called a here document where you can include a portion of the source script as stdin to a command. One frequent use is to simply print out a portion of the source script via the cat command. There are a number of options to here documents.

Woudn't it be nice if batch had a similar feature that allowed you to print out a portion of the source script

People have been doing similar things within batch using FOR loops coupled with FINDSTR, but the syntax is not very elegant.

But the amazing behavior of the erroneous (GOTO) 2>nul has enabled me to create a new PrintHere.bat utility that offers downright sexy syntax And I have provided similar options as the unix here doc, except you get to choose what leading characters are stripped

- The first time I use it to return to the parent script so I can retrieve the full path to the script, and then I CALL PrintHere a 2nd time.

- The second time through I use it to return permanently to the parent script and then GOTO the terminating :Label.

I actually used it a 3rd time for error processing, though it wasn't really necessary. I have multiple places where I detect errors, and I wanted an error handling routine that would take arguments, do certain processing, and then abort the utility. So I created :exitErr which uses (GOTO) to return to the root of PrintHere so that EXIT /B returns to the parent script.

Below is the magic code. Full documentation is embedded within the script.

Note that the code includes a tab character that does not post properly to this site. It appears where I define the tab variable, just below the :start label. You will have to edit that character when you copy the script. Alternatively, you can download PrintHere.bat.txt from my dropbox, and then simply rename it to PrintHere.bat.

PrintHere.batEdit version 1.1 - Fixed bug where empty lines were not printed properly if /E option not used

@echo off & setlocal disableDelayedExpansion & goto :start::PrintHere.bat version 1.1 by Dave Benham::::::call PrintHere [/E] [/- "TrimList"] :Label ["%~f0"]:::call PrintHere [/E] [/- "TrimList"] :Label "%~f0" | someCommand & goto :Label:::PrintHere /?:::PrintHere /V:::::: PrintHere.bat provides functionality similar to the unix here doc feature.::: It prints all content between the CALL PrintHere :Label line and the::: terminating :Label. The :Label must be a valid label supported by GOTO, with::: the additional constraint that it not contain *. Lines are printed verbatim,::: with the following exceptions and limitations::::::: - Lines are lmited to 1021 bytes long::: - Trailing control characters are stripped from each line:::::: The code should look something like the following::::::: call PrintHere :Label::: Spacing and blank lines are preserved:::::: Special characters like & < > | ^ ! % are printed normally::: :Label:::::: If the /E option is used, then variables between exclamation points are::: expanded, and ! and ^ literals must be escaped as ^! and ^^. The limitations::: are different when /E is used::::::: - Lines are limited to ~8191 bytes long::: - All characters are preserved, except !variables! are expanded and ^! and::: ^^ are transformed into ! and ^:::::: Here is an example using /E::::::: call PrintHere /E :SubstituteExample::: Hello !username!^!::: :SubstituteExample:::::: If the /- "TrimList" option is used, then leading "TrimList" characters::: are trimmed from the output. The trim characters are case sensitive, and::: cannot include a quote. If "TrimList" includes a space, then it must::: be the last character in the list.:::::: Multiple PrintHere blocks may be defined within one script, but each::: :Label must be unique within the file.:::::: PrintHere must not be used within a parenthesized code block.:::::: Scripts that use PrintHere must use \r\n for line termination, and all lines::: output by PrintHere will be terminated by \r\n.:::::: All redirection associated with a PrintHere must appear at the end of the::: command. Also, the CALL can include path information::::::: call "c:\utilities\PrintHere.bat" :MyBlock>test.txt::: This line is written to test.txt::: :MyBlock:::::: PrintHere may be used with a pipe, but only on the left side, and only::: if the source script is included as a 2nd argument, and the right side must::: explicitly and unconditionally GOTO the terminating :Label.:::::: call PrintHere :PipedBlock "%~f0" | more & goto :PipedBlock::: text goes here::: :PipedBlock:::::: Commands concatenated after PrintHere are ignored. For example::::::: call PrintHere :ignoreConcatenatedCommands & echo This ECHO is ignored::: text goes here::: :ignoreConcatenatedCommands:::::: PrintHere uses FINDSTR to locate the text block by looking for the::: CALL PRINTHERE :LABEL line. The search string length is severely limited::: on XP. To minimize the risk of PrintHere failure when running on XP, it is::: recommended that PrintHere.bat be placed in a folder included within PATH::: so that the utility can be called without path information.:::::: PrintHere /? prints out this documentation.:::::: PrintHere /V prints out the version information:::::: PrintHere.bat was written by Dave Benham. Devlopment history may be traced at:::: http://www.dostips.com/forum/viewtopic.php?f=3&t=6537:::

:startset "tab= " NOTE: This value must be a single tab (0x09), not one or more spacesset "sp=[ %tab%=,;]"set "sp+=%sp%%sp%*"set "opt="set "/E="set "/-="

Hi Dave, I know this is an older thread but I was trying out this utility and found a couple of issues in case you are interested:Issue #1: Empty lines are not echoed correctly if trimming spaces/tabs (or maybe all characters)

T:\>test.cmdBEGIN ---------------------------------------------ERROR: Unable to locate CALL PrintHere :testlabel1'DELETE' is not recognized as an internal or external command,operable program or batch file.'DROP' is not recognized as an internal or external command,operable program or batch file.'CREATE' is not recognized as an internal or external command,operable program or batch file.'.import' is not recognized as an internal or external command,operable program or batch file.'INSERT' is not recognized as an internal or external command,operable program or batch file.'DROP' is not recognized as an internal or external command,operable program or batch file.END ---------------------------------------------T:\>

Ugh I had a stupid copy/paste bug for the section of code that uses SET /P to read the file. I copied code from the section that uses FOR /F and forgot to edit a small piece of code. I updated the code in my first post to version 1.1.

mirrormirror wrote:Issue #2: If the CALL line to "printhere.bat" has preceding whitespace AND the [trim] option is not being used then failure results:...Notice the <TAB> before CALL printhere.bat.

I cannot reproduce your problem - it works fine for me. Make sure that the tab variable definition contains a <TAB> character, and not a <SPACE>. It is defined immediately after the :start label at the end of the documentation.[code]