for loop with findstr going through multiple directories

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
jerry8989
Posts: 3
Joined: 30 Jul 2014 14:27

for loop with findstr going through multiple directories

#1 Post by jerry8989 » 30 Jul 2014 14:34

Hello,

I'm trying to find a way to create a batch file that will cycle through text files in the directory I set plus it's subdirectories.
The word I'm searching for has to be the first word on the line. With the loop I need to print out the file name then below it any lines that have the word "ERRORS" as the first word in the line.

ex.
c:\temp\test1.txt
-----------------
ERRORS: This is a line with ERRORS

c:\temp\test2.txt
-----------------
ERRORS: This is another line with ERRORS

Here is the code i'm working with that isn't working
for /f c:\temp %%G in (*.log) do (Findstr /B "ERRORS:" %%G)

Thank you

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

Re: for loop with findstr going through multiple directories

#2 Post by dbenham » 30 Jul 2014 15:53

No batch file is required. One simple FINDSTR command should give you all you need:

Code: Select all

findstr /bs ERROR: "c:\temp\*.txt"

However, there is a FINDSTR /S option bug that can lead to missed matches if your folders contain file name extensions longer than 3 characters like *.txt2

The following works around the bug:

Code: Select all

for /r "c:\temp" %F in (.) do @findstr /b ERROR: "%~fF\*.txt" 2>nul

If used in a batch script, then the percents must be doubled:

Code: Select all

@echo off
for /r "c:\temp" %%F in (.) do findstr /b ERROR: "%%~fF\*.txt" 2>nul


Dave Benham

jerry8989
Posts: 3
Joined: 30 Jul 2014 14:27

Re: for loop with findstr going through multiple directories

#3 Post by jerry8989 » 31 Jul 2014 06:45

dbenham,

thank you for your reply.

The issue I'm having with FINDSTR is that it will put the full file path first then the line that the word is found on.
I need to show the file that it is looking at one time then list all the lines that have the word below it. It would need to do that for each file with the txt extension in the folder listed and sub-folders.

I was using the for loop because I read that it would stop the listing of the full file path when a line matches the find.

jerry8989
Posts: 3
Joined: 30 Jul 2014 14:27

Re: for loop with findstr going through multiple directories

#4 Post by jerry8989 » 31 Jul 2014 07:15

dbenham,

Thank you again for your help. I was able to figure out my issue by doing the following:

Code: Select all

Set _OutFile=c:\temp\temp.txt
If Exist "%_OutFile%" Del "%_OutFile%"
For /F "Tokens=* Delims=" %%I In ('Dir /A-D /B /S "c:\temp\*.log"') Do (
(Echo.
Echo.%%~I
Echo.---------------------------------------------------------------------------------------------------
)>>"%_OutFile%"
Findstr /B /C:"ERROR:"  "%%I">>"%_OutFile%"
)


If you see any future issues with this approach please let me know.

Thank you again.

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

Re: for loop with findstr going through multiple directories

#5 Post by foxidrive » 31 Jul 2014 09:29

jerry8989 wrote:If you see any future issues with this approach please let me know.


It's just less efficient, slower.

For many people that doesn't matter - for some it does.

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

Re: for loop with findstr going through multiple directories

#6 Post by dbenham » 31 Jul 2014 11:30

As foxidrive said, your approach is not particularly efficient.

I believe a more efficient method is to add an extra FOR /F to my approach and detect whenever the filename prefix changes. I haven't actually done the timing comparisons however.

ListErrs.bat

Code: Select all

@echo off
set "prior="
for /r "%~f1" %%F in (.) do for /f "tokens=1,2* delims=:" %%A in (
  'findstr /b ERROR: "%%~fF\*.log" 2^>nul'
) do (
  set "file=%%A:%%B"
  setlocal enableDelayedExpansion
  if "!file!" neq "!prior!" (
    endlocal
    echo(
    echo %%A:%%B
    echo --------------------------------------------------
    set "prior=%%A:%%B"
  ) else endlocal
  echo %%C
)

Simply pass the root folder as the one and only argument (required). use a dot to represent the current directory. You can easily redirect the output of the script if you want to create an output file.

Code: Select all

ListErrs c:\temp >c:\temp\temp.txt


Dave Benham

Post Reply