How to concat new line character in windows batch script

I have the following code

@echo off 
setlocal enableextensions disabledelayedexpansion

set "search=hello"
set "replace=hello world"

set "textFile=hello.text"

for /f "delims=" %%i in ('type "%textFile%" ^& break ^> "%textFile%" ') do (
    set "line=%%i"
    setlocal enabledelayedexpansion
    >>"%textFile%" echo(!line:%search%=%replace%!
    endlocal
)

How can I add new line character between Hello and world using this script

My hello.txt contains the following:

def a=1
config{
    hello
}

I want to change into

def a=1
config{
    hello
    world
}

The main aim is to add world after hello in the next line

Upvotes: 0

Views: 1071

Answers (1)

aschipfl
aschipfl

Reputation: 34989

By modifying the replacement string you could achieve what you want:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

set "search=hello"
rem // In the following, the empty lines are intentional; ensure that there are not even (trailing) spaces!
set replace=hello^^^

^

    world

set "textFile=hello.txt"

for /F "delims=" %%i in ('type "%textFile%" ^& break ^> "%textFile%" ') do (
    set "line=%%i"
    setlocal EnableDelayedExpansion
    >>"%textFile%" echo(!line:%search%=%replace%!
    endlocal
)

endlocal
exit /B

With the sequence ^^^ + line-break + line-break + ^ + line-break + line-break you build a double-escaped line-break, which will result in the string ^ + line-break + line-break to be assigned to the variable replace. This is going to expand to a single line-break during expansion of the expression %replace%.


The aforementioned script unfortunately uses a line-feed character only as the line-break in the replacement string instead of carriage-return plus line-feed as would be Windows-conform. To overcome that issue, the following script may be used instead:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define a line-break (carriage-return plus line-feed):
for /F %%l in ('copy /Z "%~f0" nul') do (set ^"nl=%%l^
%=empty line =%
^")

set "search=hello"
rem // Use defined line-break variable here (it will not yet be expanded here):
set "replace=hello!nl!    world"

set "textFile=hello.txt"

setlocal EnableDelayedExpansion
rem // At this point the line-break variable is going to be expanded:
for %%j in ("%replace%") do (
    rem /* Use `findstr /N` rather than `type` to precede every line with
    rem    line number plus `:` to avoid loss of empty lines due to `for /F`: */
    for /F "delims=" %%i in ('findstr /N "^^" "!textFile!" ^& break ^> "!textFile!"') do (
        endlocal & set "line=%%i" & setlocal EnableDelayedExpansion
        rem // Remove line number prefix:
        set "line=!LINE:*:=!"
        rem // Actually perform sub-string replacement:
        >>"!textFile!" echo(!line:%search%=%%~j!
    )
)
endlocal

endlocal
exit /B

This approach also maintains blank lines in the text file.

Upvotes: 2

Related Questions