Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can a batch script do the equivalent of "cat << eof"?

Tags:

batch-file

In Linux (Bash) there is a very useful functionality for dumping literal text out to another file like this:

cat > see.txt << EOF
contents going into
my file
EOF

What I need is the equivalent for a Windows batch script. I haven't found this kind of functionality built-in, but I was thinking I could write a subroutine to do it (I don't want to rely on anything that isn't natively in Windows since XP), but I'm having trouble. Here's what I have so far with help from various sources:

call:catMyChunk myCustomText c:\see.txt
exit /b

goto:myCustomText
   This is my test file
   Hope you like it.

    <got these>
    % and these %
    ! these too

   yeah
:myCustomText

:catMyChunk
    ::Should call this function with 2 args, MYDELIM and outFile.txt
    ::where is to be catted to outFile.txt
    ::and text starts with <beginning of line>goto:MYDELIM
    ::and ends with <beginning of line>:MYDELIM
    set searchStart=goto:%~1
    set searchStop=:%~1
    set outFile=%~2
    set startLine=0
    set endLine=0
    for /f "delims=:" %%a in ('findstr -b -n !searchStart! %~dpnx0') do set "startLine=%%a"
    for /f "delims=:" %%a in ('findstr -b -n !searchStop!  %~dpnx0') do set "endLine=%%a"

    set /a linesLeftToRead=%endLine% - %startLine%
    del %outFile%
    if "%linesLeftToRead%" LEQ "0" (
        echo Error finding start and end delmieters for %searchStop% in catMyChunk routine
        exit /B 1
    )
    setlocal DisableDelayedExpansion
    for /f "usebackq skip=%startLine% delims=" %%a in (`"findstr /n ^^ %~dpnx0"`) do (
        set "oneLine=%%a"
        setlocal EnableDelayedExpansion
        set "oneLine=!oneLine:*:=!"
        set /a linesLeftToRead-=1
        if !linesLeftToRead! LEQ 0 exit /B
        echo(!oneLine!>>%outFile%
    )

goto: EOF

So my requirement is that the chunk of text is output literally without any changes whatsoever (i.e. I don't want to have to escape blank lines, %, !, <, etc.). This code is doing almost everything I need, except I haven't found a way to get the exclamation points output properly. Here is the output I get, which isn't quite right:

   This is my test file
   Hope you like it.

    <got these>
    % and these %
     these too

   yeah

Edit: For anyone wanting the modified version of the subroutine that now works, here it is:

:catMyChunk
    ::Should call this function with 2 args, MYDELIM and outFile.txt
    ::where is to be catted to outFile.txt
    ::and text starts with <beginning of line>goto:MYDELIM
    ::and ends with <beginning of line>:MYDELIM
    set searchStart=goto:%~1
    set searchStop=:%~1
    set outFile=%~2
    set startLine=0
    set endLine=0
    for /f "delims=:" %%a in ('findstr -b -n !searchStart! %~dpnx0') do set "startLine=%%a"
    for /f "delims=:" %%a in ('findstr -b -n !searchStop!  %~dpnx0') do set "endLine=%%a"

    set /a linesLeftToRead=%endLine% - %startLine%
    del %outFile%
    if "%linesLeftToRead%" LEQ "0" (
        echo Error finding start and end delmieters for %searchStop% in catMyChunk routine
        exit /B 1
    )
    setlocal DisableDelayedExpansion
    for /f "usebackq skip=%startLine% delims=" %%a in (`"findstr /n ^^ %~dpnx0"`) do (
        set "oneLine=%%a"
        set /a linesLeftToRead-=1
        setlocal EnableDelayedExpansion
        set "oneLine=!oneLine:*:=!"
        if !linesLeftToRead! LEQ 0 exit /B
        echo(!oneLine!>>%outFile%
        endlocal
    )
    endlocal

goto: EOF
like image 445
Jared Avatar asked Oct 31 '11 13:10

Jared


People also ask

What is << EOF in shell script?

Basically <<EOF tells the shell that you are going to enter a multiline string until the "tag" EOF. You can name this tag as you want, it's often EOF or STOP. EOF Parameter Example. Save EOF Output.

How do you use EOF and cat?

cat with <<EOF>> will create or append the content to the existing file, won't overwrite. whereas cat with <<EOF> will create or overwrite the content.

How do you echo EOF?

There is no way to echo out an EOF. An EOF can only be generated either by reaching the end of a file or by invoking the keypress bound to the eof terminal setting ( Ctrl D by default) when the file being read is bound to the terminal. isn't EOF defined as -1 in stdio. h?

How do you end a batch file in a script?

EXIT /B at the end of the batch file will stop execution of a batch file. use EXIT /B < exitcodes > at the end of the batch file to return custom return codes.


1 Answers

Your code is missing a single endlocal in your FOR-loop.

You will then create for each loop a new local-context through the setlocal EnableDelayedExpansion, this will explode with some more lines in your text file.

Also, to preserve the exclamation marks (and also the carets) you need the toggling technique: DOS batch files: How to read a file?

setlocal DisableDelayedExpansion
for /f "usebackq skip=%startLine% delims=" %%a in (`"findstr /n ^^ %~dpnx0"`) do (
    set "oneLine=%%a"
    setlocal EnableDelayedExpansion
    set "oneLine=!oneLine:*:=!"
    set /a linesLeftToRead-=1
    if !linesLeftToRead! LEQ 0 exit /B
    echo(!oneLine!>>%outFile%
    endlocal
)
like image 88
jeb Avatar answered Nov 14 '22 05:11

jeb