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

后端 未结 2 1314
醉酒成梦
醉酒成梦 2020-12-29 17:49

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 int         


        
2条回答
  •  爱一瞬间的悲伤
    2020-12-29 18:21

    +1, Interesting application! I modified your code for a simpler and faster version:

    @echo off
    call :catMyChunk myCustomText see.txt
    exit /b
    
    goto:myCustomText
    This is my test file
    Hope you like it.
    
    % 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 goto:MYDELIM
    ::and ends with :MYDELIM
    setlocal DisableDelayedExpansion
    set searchStart=goto:%~1
    set searchStop=:%~1
    set outFile=%~2
    if exist %outFile% del %outFile%
    set copyFlag=No
    echo No> copyFlag
    for /f "delims=" %%a in (%~f0) do (
        set "oneLine=%%a"
        setlocal EnableDelayedExpansion
        if !copyFlag! == No (
            if !oneLine! == %searchStart% echo Yes> copyFlag
        ) else (
            if !oneLine! == %searchStop% (
                echo No> copyFlag
            ) else (
                echo/!oneLine!>> %outFile%
            )
        )
        endlocal
        set /p copyFlag=< copyFlag
    )
    endlocal
    goto :eof
    

    I also created another version that looks more like the Linux version, that is, the lines to copy are placed directly after invoking the routine, and the execution continue after the last copied line. Of course, to make this possible the routine is not invoked via call, but entered with a goto, and when the routine ends it execute a goto %MYDELIM% instead of a "return" (exit /b or goto :eof). Also, because a goto can not have parameters, the "parameters" are defined in variables before the invocation.

    @echo off
    set searchStop=EndOfMyText
    set outFile=see.txt
    goto :catMyChunk EndOfMyText
    This is my test file
    Hope you like it.
    
    % and these %
    ! these too
    yeah
    :EndOfMyText
    exit /b
    
    
    :catMyChunk
    ::Before JUMP to this "function" define 2 vars: searchStop and outFile
    ::where is to be catted to %outFile%
    ::and text starts with goto :catMyChunk %searchStop%
    ::and ends with :%searchStop%
    setlocal DisableDelayedExpansion
    set searchStart=goto :catMyChunk %searchStop%
    if exist %outFile% del %outFile%
    set copyFlag=No
    echo No> copyFlag
    for /f "delims=" %%a in (%~f0) do (
        set "oneLine=%%a"
        setlocal EnableDelayedExpansion
        if !copyFlag! == No (
            if /I !oneLine! == !searchStart! echo Yes> copyFlag
        ) else (
            if !oneLine! == :%searchStop% (
                echo No> copyFlag
            ) else (
                echo/!oneLine!>> %outFile%
            )
        )
        endlocal
        set /p copyFlag=< copyFlag
    )
    endlocal
    goto %searchStop%
    

    EDIT

    This new version is even faster and now works with all special cases, including empty lines:

    :catMyChunk
    ::Should call this function with 2 args, MYDELIM and outFile.txt
    ::where is to be catted to outFile.txt
    ::and text starts with goto:MYDELIM
    ::and ends with :MYDELIM
    setlocal EnableDelayedExpansion
    set searchStart=goto:%~1
    set searchStop=:%~1
    set outFile=%~2
    if exist %outFile% del %outFile%
    findstr /n ^^ "%~f0" > pipeline.txt
    call :seekMyChunk < pipeline.txt
    del pipeline.txt
    exit /B
    
    :seekMyChunk
    set oneLine=:EOF
    set /P oneLine=
    if !oneLine! == :EOF goto startNotFound
    set oneLine=!oneLine:*:=!
    if not !oneLine! == %searchStart% goto seekMyChunk
    :catNextLine
    set oneLine=:EOF
    set /P oneLine=
    if !oneLine! == :EOF goto stopNotFound
    set oneLine=!oneLine:*:=!
    if !oneLine! == %searchStop% goto :eof
    echo/!oneLine!>> %outFile%
    goto catNextLine
    :startNotFound
    echo Error finding start delimiter for %searchStart% in catMyChunk 
    goto :eof
    :stopNotFound
    echo Error finding stop delimiter for %searchStop% in catMyChunk 
    goto :eof
    

提交回复
热议问题