find string with multiple instances and copy all to file.

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
ladduq
Posts: 31
Joined: 22 Jan 2012 01:08

find string with multiple instances and copy all to file.

#1 Post by ladduq » 11 Mar 2012 06:02

HI

Need to find a single string with multiple instances in a text file.

If the search string is matching then copy the current line and next
line of that file in to a separate text file

Example:The file C:\info\information.txt with its content is

1 Hello, how are u doing john
2 Hello, how are u doing smith
3 Hello, how are u doing ladduq
4 Hello, how are u doing john
5 Hello, how are u doing smith
6 Hello, how are u doing ladduq
7 Hello, how are u doing john
8 Hello, how are u doing smith
9 Hello, how are u doing ladduq

Here the search string is smith then
copy the current line which contains the string smith and also
its next line to a separate file.

In this case the output should be like below in results.txt file

2 Hello, how are u doing smith
3 Hello, how are u doing ladduq
===========================================
5 Hello, how are u doing smith
6 Hello, how are u doing ladduq
===========================================
8 Hello, how are u doing smith
9 Hello, how are u doing ladduq

Thanks & Regards
ladduq

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: find string with multiple instances and copy all to file

#2 Post by foxidrive » 11 Mar 2012 07:03

I want to point out that often in batch files the format and content of the text to be searched, can be used to make the task simpler.
For example, if the text includes the line numbers you have added then the task is easier.
Are you able to show us a sample of the exact text to be searched along with the keyword?

It's possible that the makeup of the text will help extract the data you need, as well as illuminate possible pitfalls that we can avoid.

abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Re: find string with multiple instances and copy all to file

#3 Post by abc0502 » 11 Mar 2012 07:09

For the lines that contain the string you search for:
@echo off
cls
set info=d:\information.txt
set results=d:\results.txt
FOR /F "tokens=*" %%1 IN ('findstr /C:"smith" %info%') DO echo %%1 >>%results%


but for the display of the next line i have no idea

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: find string with multiple instances and copy all to file

#4 Post by aGerman » 11 Mar 2012 07:37

Perhaps not the simpliest way but it should work with Windows-style text files:

Code: Select all

@echo off &setlocal
set "infile=C:\info\information.txt"
set "search=smith"
set "outfile=test.txt"

setlocal EnableDelayedExpansion
set "found="
set /a "n=0"
for /f "delims=:" %%i in ('findstr /n "\<!search!\>" "!infile!"') do (
  set "found=!found! %%i"
  set /a "n=%%i"
)

if %n%==0 goto :eof

for /f %%i in ('type "!infile!"^|find /c /v ""') do set /a "max=%%i"

>"!outfile!" (
  for %%i in (%found%) do (
    set /a "n=%%i+1"
    set "ln="
    (
      for /l %%j in (1,1,!n!) do (
        set "lnbefore=!ln!"
        set "ln="
        set /p "ln="
      )
    )<"!infile!"
    echo(!lnbefore!
    if %%i neq %max% echo(!ln!
    echo(===========================================
  )
)

Regards
aGerman

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: find string with multiple instances and copy all to file

#5 Post by dbenham » 11 Mar 2012 14:27

I started with aGerman's code and dramatically improved performance with some significant restructuring.

The original code reads the file from the beginning for each match found. It also stored the results of the findstr in a variable.

The new version uses the findstr results directly, and only reads the file once from the beginning, always picking up where it left off.

aGerman had code to verify that there is a line following the last match before attempting to print it. I skipped that test, so if a line does not exist after the last match, the output will have a phantom blank line after the last match. Simply add the test back to the code if that is a problem.

Code: Select all

@echo off
cls
setlocal enableDelayedExpansion
set infile="information.txt"
set "search=smith"
set outfile="test.txt"

set current=1
<%infile% (
  for /f "delims=:" %%N in ('findstr /n "\<!search!\>" "!infile!"') do (
    set /a skip=%%N-1
    for /l %%i in (!current! 1 !skip!) do set /p "ln="
    if %%N geq !current! set /p "ln="
    echo(!ln!
    set "ln="
    set /p "ln="
    echo(!ln!
    echo(===========================================
    set /a current=%%N+2
  )
) >%outfile%
type test.txt


Dave Benham

ladduq
Posts: 31
Joined: 22 Jan 2012 01:08

Re: find string with multiple instances and copy all to file

#6 Post by ladduq » 12 Mar 2012 00:13

HI,

@foxidrive
@abc0502
@aGerman
@dbenham

Thank You all for replying.

@aGerman,@dbenham it works fine.Thank You

Regards
Ladduq

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: find string with multiple instances and copy all to file

#7 Post by aGerman » 12 Mar 2012 07:12

@Dave
Very clever. I wasn't quite sure how to combine FOR /F with FOR /L to avoid that it runs over the file again and again. One more snippet for my Batch collection... :)

Regards
aGerman

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: find string with multiple instances and copy all to file

#8 Post by foxidrive » 12 Mar 2012 08:20

Yes, it is clever stuff.

Can I ask though why you use ( in an echo statement, and not . or / or another character?

dbenham wrote:

Code: Select all

    echo(!ln!
    echo(===========================================


dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: find string with multiple instances and copy all to file

#9 Post by dbenham » 12 Mar 2012 09:10

@foxidrive - Read ECHO. FAILS to give text or blank line - Instead use ECHO/

There is a lot of back and forth, and the thread is kind of left hanging with no definitive answer. But it turns out ECHO( seems to be the only variant that always works. It is definitely counter-intuitive - it looks like it would interfere with balanced parentheses. Yet it has been very reliable.

Dave Benham

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: find string with multiple instances and copy all to file

#10 Post by foxidrive » 12 Mar 2012 09:34

Thanks for the link Dave.

I see that echo( is considered reliable but it makes the reading of batch files more difficult, and particularly so for people learning batch files (and when using syntax highlighting editors) and IMO we should be thinking of those people learning batch files when posting code - but maybe other people don't see things that way, I don't know.

I think that if echo. or echo/ will work in a given situation then using that is preferable to using echo( all the time.

Instead of this:
echo(===========================================
take the time to use this
echo ===========================================

Just my two cents worth.

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: find string with multiple instances and copy all to file

#11 Post by aGerman » 12 Mar 2012 15:21

Don't worry about that. In my opinion if you say we should be thinking of people learning batch scripting then we should make sure they're learning proven things. "/" isn't and "." is the worst case (even if the internet is full of it).
I'm with you that some syntax highlighters are confused and that a simple space is enough in case a known constant string is following.

Regards
aGerman

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: find string with multiple instances and copy all to file

#12 Post by Aacini » 13 Mar 2012 08:47

Although it was already solved, this topic is perfect to use my SETFILEPOINTER program. This is my solution (based on Dave's one):

Code: Select all

@echo off
cls
setlocal enableDelayedExpansion
set infile="information.txt"
set "search=smith"
set outfile="test.txt"

if not exist SetFilePointer.com call :CreateSetFilePointer

rem Load line positions
set i=0
for /F "delims=:" %%a in ('findstr /O "^" %infile%') do (
   set /A i+=1
   set line[!i!]=%%a
)

<%infile% (
   for /F "delims=:" %%N in ('findstr /N "\<%search%\>" %infile%') do (
      SetFilePointer 0 !line[%%N]!
      set /P "ln="
      echo(!ln!
      set "ln="
      set /P "ln="
      echo(!ln!
      echo(===========================================
   )
) >%outfile%
type %outfile%
goto :EOF


:CreateSetFilePointer
setlocal DisableDelayedExpansion
set SetFilePointer=2ÿ³‹û‹ó2íŠMÿãE° üó®t^>Š]ÿ€û0r6€û9w1€ë0Sã+€= u^&ó®t"Of3Àf3ɱ+€é!f3ÛGŠ]ÿ€ûEt+€ûeu(uÿë%%ëyGf3ÛŠ]ÿ€û0rs€û9wnf÷á€ë0f÷Ûf+ÃëáëØëäf‹È2Àf#ÉuTþÀþÀ€<EtK€<etFFÆDÿB‹Ñ±1€é!fÓé[´BÍ!r­€|ÿBu§±1€é!fÓâ‹Ðf÷Úf‹Ê±1€é!fÓé2ÀþÀþÀ´BÍ!2À´LÍ!ë¢ë½
setlocal EnableDelayedExpansion
echo !SetFilePointer!> SetFilePointer.com
exit /B


This program should run faster if the input file is large and there are many matching lines.

ladduq
Posts: 31
Joined: 22 Jan 2012 01:08

Re: find string with multiple instances and copy all to file

#13 Post by ladduq » 20 Mar 2012 00:01

Hi

Need some help

the script should not display a line which contains a part of matching string pattern.It should stick to a whole string and search that whole string and then only display those lines as output.

For example a file contains

1 hey john i'm doing fine
2 hey john how are u
3 john i think u are good
4 john lets meet tommorrow

in this case all the line contains the string john
so if my search string is "john lets meet" then it
should output only that matching string line and
not all the lines that contain john.

in this case output expected is

4 john lets meet tommorrow

Regards
Ladduq

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: find string with multiple instances and copy all to file

#14 Post by Aacini » 20 Mar 2012 02:13

Yes, there was a small bug in aGerman's original code (/C switch missed in findstr command). It is fixed in the Batch file below:

Code: Select all

@echo off
cls
setlocal enableDelayedExpansion
set "infile=information.txt"
set "search=john lets meet"
set "outfile=test.txt"

if not exist SetFilePointer.com call :CreateSetFilePointer

rem Load line positions
set i=0
for /F "delims=:" %%a in ('findstr /O "^" "%infile%"') do (
   set /A i+=1
   set line[!i!]=%%a
)

< "%infile%" (
   for /F "delims=:" %%N in ('findstr /N /C:"%search%" "%infile%"') do (
      SetFilePointer 0 !line[%%N]!
      set /P "ln="
      echo(!ln!
      set "ln="
      set /P "ln="
      echo(!ln!
      echo(===========================================
   )
) > "%outfile%"
type "%outfile%"
goto :EOF


:CreateSetFilePointer
setlocal DisableDelayedExpansion
set SetFilePointer=2ÿ³‹û‹ó2íŠMÿãE° üó®t^>Š]ÿ€û0r6€û9w1€ë0Sã+€= u^&ó®t"Of3Àf3ɱ+€é!f3ÛGŠ]ÿ€ûEt+€ûeu(uÿë%%ëyGf3ÛŠ]ÿ€û0rs€û9wnf÷á€ë0f÷Ûf+ÃëáëØëäf‹È2Àf#ÉuTþÀþÀ€<EtK€<etFFÆDÿB‹Ñ±1€é!fÓé[´BÍ!r­€|ÿBu§±1€é!fÓâ‹Ðf÷Úf‹Ê±1€é!fÓé2ÀþÀþÀ´BÍ!2À´LÍ!ë¢ë½
setlocal EnableDelayedExpansion
echo !SetFilePointer!> SetFilePointer.com
exit /B

ladduq
Posts: 31
Joined: 22 Jan 2012 01:08

Re: find string with multiple instances and copy all to file

#15 Post by ladduq » 20 Mar 2012 06:44

Hi

Its not working as the expected output mentioned above.

Even it is displaying the output if it matches a
part of search string. :(

Regards
Ladduq

Post Reply