Search code examples
batch-filecmdfindstr

FINDSTR - add "date modified" of the files as a prefix to each result


I'm looking for some commands to add to my script. The script goes through a folder of text log files and looks for a string passed as input.
Unfortunately, the log files overflow at a set size and don't have their date in the file name, just a number suffix and a string prefix. In the log file lines there is only the time of the event, not the date. The date is added as a single line at 12 o'clock.

Example of the file folder where the search is done:

Logfile_001.txt
Logfile_002.txt
Reboot-01_Logfile_001.txt
Reboot-01_Logfile_002.txt
Reboot-01_Logfile_003.txt
Reboot-02_Logfile_001.txt
Reboot-02_Logfile_002.txt

I want to add the "date modified" attribute of the searched file in each line of the FINDSTR result.

My current code:

@ECHO off
DEL /F _Result.searchresult
SET /P searchterm=Enter search term: 
@ECHO Searching for %searchterm% >_Result.searchresult
@ECHO --------------------------------------------- >>_Result.searchresult
FINDSTR /S /C:"%searchterm%" *.txt >>_Result.searchresult
_Result.searchresult

Current result:

Reboot-79_Logfile_001.txt:08:29:05.586 loginfo
Reboot-79_Logfile_001.txt:08:30:05.586 loginfo

Wanted result:

2019/08/13 Reboot-79_Logfile_001.txt:08:29:05.586 loginfo
2019/08/13 Reboot-79_Logfile_001.txt:08:30:05.586 loginfo

Or:

Reboot-79_Logfile_001.txt:2019/08/13 08:29:05.586 loginfo
Reboot-79_Logfile_001.txt:2019/08/13 08:30:05.586 loginfo

Where "2019/08/13" is the date of the "date modified" attribute of file Reboot-79_Logfile_001.txt


Solution

  • @OP I had to make a minor Change as I wrote this on my phone on the train originally and I made a couple typos etc. that were present when you tested

    Specifically these two single character changes:

    "Tokens=1* NOT "Token=1*

    and

    SET "_DateMatched=1" NOT SET "_DateMatched="

    To do this split out the file name from the results of find string using a loop and then get the date from that to use in the echo.

    Script

    @(
      SETLOCAL
      ECHO OFF
      SET "_ResultFile=_Result.searchresult"
      SET "_DateMatched="
    )
    DEL /F /Q "%_ResultFile%"
    SET /P "_SearchTerm=Enter search term: "
    
    ECHO Searching for %_SearchTerm% >"%_ResultFile%"
    ECHO --------------------------------------------- >>"%_ResultFile%"
    
    FOR /F "Tokens=1* delims=:"  %%A IN ('
      FINDSTR /S /C:"%_SearchTerm%" *.txt
    ')  DO (
      For %%a in ( %%~tA ) Do (
        IF NOT DEFINED _DateMatched (
          ECHO.%%a %%A:%%B>>"%_ResultFile%"
          SET "_DateMatched=1"
        )
      )
      SET "_DateMatched="
    )
    

    Results

    Searching for ggg 
    --------------------------------------------- 
     08/13/2019 test.txt:ggg
     08/13/2019 test2.txt:ggg
    

    In addition, Yes you could use a FOR /F instead it was a 50/50 coin flip II didd to use the defined/not defined with a FOR loop instead of a FOR /F loop.

    However the other answer provided chose this path, but for some reason used my code as a base and added in a 3rd loop so that their middle loop is redundant.

    I'll post that alternative here as well as I had thought about posting both ways, it's six one way half a dozen the other. (but I won't waste your time with an extra loop, I am still wrapping my brain around them adding that!)

    Alternative version

    @(
      SETLOCAL
      ECHO OFF
      SET "_ResultFile=_Result.searchresult"
    )
    DEL /F /Q "%_ResultFile%"
    SET /P "_SearchTerm=Enter search term: "
    
    ECHO Searching for %_SearchTerm% >"%_ResultFile%"
    ECHO --------------------------------------------- >>"%_ResultFile%"
    
    FOR /F "Tokens=1* delims=:"  %%A IN ('
      FINDSTR /S /C:"%_SearchTerm%" *.txt
    ')  DO (
      For /F %%a in ("%%~tA") Do (
          ECHO.%%a %%A:%%B>>"%_ResultFile%"
      )
    )
    

    Although there really isn't a functional difference between each method, I waffle on whether the 1st or 2nd is more aesthetically pleasing, so it's a coin flip to me on which to write first or whether to write both at all.

    That said trying to create a rational for some of the odd comments I received on poking another for posting my code with minor essentially non functional changes, but the core of the code is still the stuff I wrote, and just chose to show the FOR /F method, but then did so in a way that makes an unnecessary 3rd loop.

    I think there are some minor benefits to the FOR /F, it saves at about 50 characters of code, and while in this case it's really 50/50, there are scenarios where I would definitely choose it as being a bit faster as the next step, although in this case we only have 3 iterations on a match, so I suspect for the current scenario we'd need to have 10s of thousands of matches before we might noticeably affect the outcome.

    That said, by adding a 3rd unneeded loop as in the other comment, I suspect any speed benefit was nullified, so.. I'm not sure, at least in the above code I provided there isn't the unneeded loop, so if there is a speed benefit concert try use that instead. :)