Search code examples
batch-filecmdfindstr

How to search for a string in a file and copy found line and next line to another file?


I have 2 lines in a file called database.txt. One line contains a question, and the consecutive line below contains the answer.

For example:

<--When did India get it's Independence?-->
India got it's independence on August 15th, 1947.

If user searches for When,India,Independence? then the 1st line is copied into another file called result.txt. But I want both lines copied, question and answer.

Can anyone throw some light here?


Solution

  • Help topic What topics can I ask about here? should be always read first before posting a question. The Stack Overflow community is not for doing the entire programming job for others. It looks like you have not made any effort on coding a batch file for your task by yourself.

    But you have luck as I was interested in the challenge to find 1 or more lines in a text file and copy the found lines as well as 1 or more lines below each found line to another text file using only standard commands and applications of Windows.

    I usually do such tasks with text editor UltraEdit with its powerful Perl regular expression engine and scripting support and would have never come on the idea to use a batch file for grabbing lines from a text file and store them in another text file.

    Here is a general batch file solution with explaining comments for copying found lines and 2 to N (see LineCount) consecutive lines below each found line from one text file to another text file.

    @echo off
    setlocal EnableDelayedExpansion
    
    rem Define the regular expression search string.
    set "SearchExpression=When.*India.*Independence"
    
    rem Define names of input and output file with full path.
    set "ResultFile=C:\Temp\Result.txt"
    set "SourceFile=C:\Temp\Example.txt"
    
    rem Delete existing output file from a previous execution.
    if exist "%ResultFile%" del "%ResultFile%"
    
    rem Run a regular expression search in input file using standard Windows
    rem console application FINDSTR with getting output also the line number
    rem of the line with a positive match at beginning of the output line
    rem and separated from the found line with a colon. Of interest in this
    rem first loop is only the line number being processed in subroutine.
    for /F "tokens=1 delims=:" %%N in ( '%SystemRoot%\System32\findstr.exe /R /N "%SearchExpression%" "%SourceFile%"' ) do (
        set SkipLines=%%N
        call :CopyLines
    )
    endlocal
    goto :EOF
    
    rem Subroutine to copy from input file the line with the positive match
    rem of the regular expression search and also the next line in the file.
    :CopyLines
    
    rem Determine the number of lines to copy from input file to output file.
    set LineCount=2
    set SkipOption=
    
    rem Skip all lines above the found line.
    set /A SkipLines-=1
    
    rem Option skip with value 0 results in a syntax error message.
    rem Therefore define option skip only with a value greater 0.
    if not "%SkipLines%" == "0" set "SkipOption=skip=%SkipLines% "
    
    rem Copy LineCount lines starting from SkipLines+1 line to output file.
    for /F "usebackq %SkipOption%delims=" %%L in ( "%SourceFile%" ) do (
       echo %%L>>"%ResultFile%"
       set /A LineCount-=1
       if "!LineCount!" == "0" goto :EOF
    )
    

    And here is one more batch file without comments optimized for copying just each found line and the line below from input to output text file.

    @echo off
    setlocal EnableDelayedExpansion
    set "SearchExpression=When.*India.*Independence"
    set "ResultFile=C:\Temp\Result.txt"
    set "SourceFile=C:\Temp\Example.txt"
    if exist "%ResultFile%" del "%ResultFile%"
    for /F "tokens=1,2* delims=:" %%N in ( '%SystemRoot%\System32\findstr.exe /R /N "%SearchExpression%" "%SourceFile%"' ) do (
        set SkipLines=%%N
        echo %%O>>"%ResultFile%"
        call :CopyNextLine
    )
    endlocal
    goto :EOF
    
    :CopyNextLine
    for /F "usebackq skip=%SkipLines% delims=" %%L in ( "%SourceFile%" ) do (
       echo %%L>>"%ResultFile%"
       goto :EOF
    )