Reputation: 85
I want to create a batch file which will read a .log file, then picks up errors from it and append to a .txt file. But I don't want the batch to rewrite .txt every time, so now I am looking to compare the last modification timestamps of both these files and then append the latest updation only. Following is the batch file
@echo off
color 3
cls
@FOR %%A IN ("%ProgramFiles(x86)%\Apache Software Foundation\Apache2.2\logs\error.log") DO @(ECHO=%%~tA& set timestamp=%%~tA)
echo %timestamp%
@FOR %%A IN ("D:\error.txt") DO @(ECHO=%%~tA& set timestamp2=%%~tA)
echo %timestamp2%
if %timestamp% gtr %timestamp2% (
set DirToSearch="C:\Program Files (x86)\Apache Software Foundation\Apache2.2\logs"
set LineToRead="error"
pushd %DirToSearch%
for /r %%f in (error.log) do (
For /F "tokens=*" %%l in ('Findstr /L /I %LineToRead% "%%f"') do (
if %%l equ " " (
echo File:"%%f" is Not OK >> D:\FileStatus.txt
) else (
echo Line: %%l>>D:\error.txt
)
)
)
Goto :End
:End
popd
)
pause
exit
Now here I am unable to compare the timestamps It would be great help if anyone contributes to achieve this.
Upvotes: 0
Views: 295
Reputation: 80033
@echo off
SETLOCAL
set "DirToSearch=C:\Program Files (x86)\Apache Software Foundation\Apache2.2\logs"
set "processedfile=D:\error.txt"
set "LineToRead=error"
pushd %DirToSearch%
COPY "%processedfile%" ".\processedfile.log" >nul 2>nul
for /f "delims=" %%a in ('dir /b /a-d /od *.log') do (
if /i "%%a"=="error.log" goto end
if /i "%%a"=="processedfile.log" goto process
)
:process
for /r %%f in (error.log) do (
For /F "tokens=*" %%l in ('Findstr /L /I /C:"%LineToRead%" "%%f"') do (
if %%l equ " " (
echo File:"%%f" is Not OK >> D:\FileStatus.txt
) else (
echo Line: %%l>>D:\error.txt
)
)
)
:end
del "processedfile.log"
popd
pause
exit
I've removed the fluff from the code.
Note that after an @echo off
statement, @
at the start of a command is redundant (@command
means "don't echo the command)
The setlocal
command ensures that changes made to the environment are discarded when the batch terminates.
Note the new position of the quotes - to ensure that the value assigned to the variable does not include any possible stray trailing spaces.
After switching directory, the processed file is copied
to the current directory in a unique name (whatever name you choose, as long as it has a .log
extension) - this places a copy of the file in the log directory, so that the magic can be performed.
The dir
command reports the names of the .log
files found; /od
provides the list in timestamp order. Therefore, whichever of the two files error.log
and processedfile.log
occurs first in the list will cause the code to branch to either process
to process the data (the processedfile.log
file is earlier than the error.log
so new data has been added) or end
(error.log
is earlier, so no new data has been added)
I've made only one minor change to your findstr
- added /c:
and quoted the target string. This is largely redundant, but if you change the string to include a space, it provides a verbatim target for findstr
. The remainder of that processing as as it was as I don't know the exact details of the processing required.
Note that in your code, DirToSearch
and LineToRead
were being re-assigned within the code block (series of lines enclosed in parentheses). This would not work because the entire code block is parsed then executed, and the parsing process replaces any %var%
with its value at parse time. Your code failed to fail - because you were not using a setlocal
, once the code had run, the variables remained assigned, and the code on future runs would use the value assigned in the prior run.
Note that :
is not required in a goto
except in the specific goto :eof
which means "go to end-of-file".
Your goto end
is redundant, as end
directly follows the goto
- but again, it fails to fail. A label within a code block terminates the block. In this case, it was irrelevant since nothing important followed the label.
Having reached the label :end
, the process now deletes the copy of the processed file and pops the original directory back with a popd
instruction.
Upvotes: 1