The Batch file below do exactly what you requested:
@echo off
setlocal EnableDelayedExpansion
rem Define CR variable containing a Carriage Return (0x0D)
for /F %%a in ('copy /Z "%~F0" NUL') do set "CR=%%a"
rem Define LF variable containing a Line Feed (0x0A)
set LF=^
%Do not remove%
%these lines%
rem Define the string to find
set "find=<tree_node>!CR!!LF!"
set "find=!find! <rule_name>bla</rule_name>!CR!!LF!"
set "find=!find! <rule_argument>bla</rule_argument>!CR!!LF!"
set "find=!find! <acl_name>bla</acl_name>!CR!!LF!"
set "find=!find!</tree_node>"
rem Get the number of lines to copy
findstr /N /R /C:"!find!" input.txt > findstr.tmp
for /F "delims=:" %%a in (findstr.tmp) do set /A lines=%%a+4
del findstr.tmp
rem Read from input file
< input.txt (
rem Copy the appropriate number of lines
for /L %%i in (1,1,%lines%) do (
set /P "line="
echo !line!
)
rem Add the new lines
echo ^<tree_node^>
echo ^<rule_name^>TEST1^</rule_name^>
echo ^<rule_argument^>TEST2^</rule_argument^>
echo ^<acl_name^>TEST3^</acl_name^>
echo ^</tree_node^>
rem Copy the rest of lines
findstr "^"
rem Write to output file
) > output.txt
move /Y output.txt input.txt
For a further description on the method used to find the multi-line string, see this answer.
EDIT: How to define a larger search text
The findstr
command have a limit in the length of the multi-line string used to search text in the file. However, you don't need to include each and every character of such a part in the multi-line string! You may use a shorter string comprised of a regex that cover several characters in the file; for example, the .*
regex match any number of characters that are delimited by the characters placed before and after it. In this way, you just need to include enough parts in the search text in order to made it unique in the file.
For example, if there is just one <rule_name>bla</rule_name>
section in the file, then the same five-lines search string in this code may be defined with this shorter text:
rem Define the string to find
set "find=<tree_node>!CR!!LF!"
set "find=!find! <rule_name>bla</rule_name>!CR!!LF!"
set "find=!find!.*!CR!!LF!"
set "find=!find!.*!CR!!LF!"
set "find=!find!</tree_node>"