Batch or script to scan dated file for certain text

murryc
murryc used Ask the Experts™
on
I have a daily log file that gets created in the format yymmdd.skd.  I would like to scan all files in the folder that contain these skd files.  The scan would check only files with the date of the current day or newer.  So if today is 120416.skd, then it would check for files 120416.skd and 120417.skd, etc, but not older files than the current day.

The scan would check each file for the string ,,CM, (comma comma CM comma).

It needs to output the number of times it finds the string to a text file, just the total count.  So the text file could say the following....

Found XX CM1 entries on schedule 120416.skd

If it does not find any entries of ,,CM, then it needs to make it obvious.

DID NOT FIND any CM1 entries on schedule 120416.skd.

Since it will be scanning multiple files each day, the text output would likely contain multiple file results.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Robert SchuttSoftware Engineer

Commented:
How about this .vbs:

Option Explicit

Const C_FOLDER = "c:\temp\logging"
Const C_EXT = ".skd"
Const C_FILE_OUT = "scan.log"

Const C_SEARCH_TEXT = ",,CM,"

Dim oFSO, sDate, oOutFile, oFolder, oFile, bProcessFile, iCount, oTS, sLine, sOutput

Set oFSO = CreateObject("Scripting.FileSystemObject")

sDate = FormatDateTime(Now)
sDate = Mid(sDate,3,2) & Mid(sDate,6,2) & Mid(sDate,9,2)
'WScript.Echo "Current date = '" & sDate & "'"
Set oFolder = oFSO.GetFolder(C_FOLDER)
Set oOutFile = oFSO.OpenTextFile(C_FILE_OUT, 2, True)
For Each oFile In oFolder.Files
	'WScript.Echo "checking file '" & oFile.Name & "'"
	bProcessFile = False
	If Len(oFile.Name) = 6 + Len(C_EXT) Then If IsNumeric(Left(oFile.Name, 6)) And Right(oFile.Name, Len(C_EXT)) = C_EXT Then bProcessFile = (Left(oFile.Name, 6) >= sDate)
	If bProcessFile Then
		iCount = 0
		Set oTS = oFile.OpenAsTextStream(1, 0) ' For Reading, as ASCII
		While Not oTS.AtEndOfStream
			sLine = oTS.ReadLine()
			If InStr(sLine, C_SEARCH_TEXT) > 0 Then iCount = iCount + 1
		Wend
		oTS.Close
		Set oTS = Nothing
		If iCount = 0 Then
			sOutput = "DID NOT FIND any CM1 entries on schedule " & oFile.Name
		Else
			sOutput = "Found " & iCount & " CM1 entries on schedule " & oFile.Name
		End If
		'WScript.Echo sOutput
		oOutFile.WriteLine sOutput
	Else
		'WScript.Echo "skip file '" & oFile.Name & "'"
	End If
Next
oOutFile.Close
Set oOutFile = Nothing
Set oFolder = Nothing
Set oFSO = Nothing

Open in new window

I don't presume this is a solution at all. I comment because I love these little text-based questions...

Suppose a line contains no more than just one occurance of ',,CM,' then the following DOS batch code would do the job quite nicely:
@echo off
for /f %%a in ('xcopy *.skd "%temp%" /l /d:%date:~-10% ^| find /v "File(s)"') do (
  for /f "tokens=3 delims=:" %%b in ('find /c ",,CM," "%%a"') do (
    if %%b equ 0 (
      echo DID NOT FIND any CM1 entries on schedule %%~nxa
    ) else (
      echo Found %%b CM1 entries on schedule %%~nxa
) ) )

Open in new window

NOTE: The '%date:~-10%' part of the XCOPY command is set to accept dates in the format 'mm-dd-yyyy' so may need tweaking if your date format is different.

NOTE: The XCOPY command DOES NOT copy nor effect any files on your hard drive whatsoever. It is used purely to return the names of files created or last modified on, or after, a particular date.
Qlemo"Batchelor", Developer and EE Topic Advisor
Top Expert 2015
Commented:
As a cmd batch file:
@echo off
setlocal EnableDelayedExpansion
pushd d:\FolderToCheck

set today=%date:~-4%%date:~10,2%%date:~-7,2%
dir /od *.skd > %temp%\skd
for/F "delims=[]" %%L in ('find /N "%today%" %temp%\skd') do ^
for /F %%F in ('more +%%L %temp%\skd') do ^
for /F %%C in ('find /C ",,CM," %%F') do (
  if %%C == 0 (set txt=DID NOT FIND any) else (set txt=Found %%C)
  echo !txt! CM1 entries on schedule %%F.>> Logfile.txt
)

Open in new window

Become a CompTIA Certified Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

Author

Commented:
Robert....attached is an actual skd file to test with (had to rename to .txt to attach), that contains zero ,,CM,.

When I run the script it creates a blank scan.log file.  Not sure what it is doing or where it is missing anything.

Paul...the date format needs to be yymmdd
120418.txt
murryc
Paul...the date format needs to be yymmdd
Yeah, but to get the current date I would need to know your system's date format. You can find it with the following command in a DOS box:

    echo %date%

Please let us know what that returns.

EDIT: (Oops! Just noticed seems like Qlemo might have it... Please confirm anyway)
Robert SchuttSoftware Engineer

Commented:
I like the other guys' solutions because I used to do a lot of shell scripting on unix and didn't know windows shell scripting had become so versatile.

The big plus point of a .vbs like this for me is total flexibility in the sense that if you need to change something like search for a RegExp or show some other field in the lines where you find the search text it's easily extendable.

I can only guess that the script as I provided it doesn't work because I defined a variable to designate the folder where the .skd files are: C_FOLDER = "c:\temp\logging"

So you would need to point that at the right location. But maybe it's possible to change it to just "." for the current directory if that's where they are.
murryc

It would have been preferable for you to have posted a file that contains some ',,CM,'s.

I Just tried my previous code. Can you try this one instead please.
@echo off
for /f "skip=1 tokens=1-3" %%a in ('WMIC Path Win32_LocalTime Get Day^, Month^, Year') do (
  for /f "tokens=*" %%f in ('xcopy *.skd "%temp%" /d:%%b-%%a-%%c /l ^| find /v "File(s)"') do (
    for /f "tokens=3 delims=:" %%g in ('find /c "for" "%%f"') do (
      if %%g equ 0 (
        echo DID NOT FIND any CM1 entries on schedule %%~nxf
      ) else (
        echo Found %%g CM1 entries on schedule %%~nxf
) ) ) )

Open in new window

Most Valuable Expert 2012
Top Expert 2014

Commented:
Here's my version of a VBS that will write the details to a CSV file with
DATE,FILENAME,SEARCHCOUNT

Regards,

Rob
strFolder = "C:\Temp\Scripts"
strOutputFile = "C:\Temp\Scripts\FileCount.csv"
strSearchString = ",,CM,"

Set objFSO = CreateObject("Scripting.FileSystemObject")
Const ForReading = 1
Const ForAppending = 8
Set objOutput = objFSO.OpenTextFile(strOutputFile, ForAppending, True)
objOutput.WriteLine """Date"",""File Name"",""CM Count"""
For Each objFile In objFSO.GetFolder(strFolder).Files
	If Right(LCase(objFile.Name), 4) = ".skd" Then
		Set objSKD = objFSO.OpenTextFile(objFile.Path, ForReading, False)
		strContents = objSKD.ReadAll
		objSKD.Close
		intCount = 0
		intPos = InStr(strContents, strSearchString)
		While intPos > 0
			intCount = intCount + 1
			strContents = Mid(strContents, intPos + 1)'Len(strSearchString))
			intPos = InStr(strContents, strSearchString)
		Wend
		If intCount > 0 Then
			'WScript.Echo intCount & " entries were found in " & objFile.Name
			objOutput.WriteLine Now & "," & objFile.Name & "," & intCount
		Else
			'WScript.Echo "No entries were found in " & objFile.Name
			objOutput.WriteLine Now & "," & objFile.Name & "," & intCount
		End If
	End If
Next
objOutput.Close

Open in new window

Author

Commented:
Paul,

not sure where your batch looks for ,,CM1,.  I ran it against the SKD and added a ,,CM1, (which is just changing any of the ,,E**, areas to ,,CM1,, but your batch did not return anything.

Rob, I knew you would show up sometime :)
Your script nailed the scan and the output.  Is there a way for it NOT to scan any skd files that exist prior to the current day?  These skd files stay in the folder for years and so scanning backwards is useless, but scanning current and forward is crucial.

Thoughts?
Most Valuable Expert 2012
Top Expert 2014
Commented:
Yes, there is a way. I haven't tested this, but give it a shot.

Regards,

Rob.

strFolder = "C:\Temp\Scripts"
strOutputFile = "C:\Temp\Scripts\FileCount.csv"
strSearchString = ",,CM,"

Set objFSO = CreateObject("Scripting.FileSystemObject")
dteToday = CDate(Day(Now) & "-" & MonthName(Month(Now), True) & "-" & Year(Now))
Const ForReading = 1
Const ForAppending = 8
Set objOutput = objFSO.OpenTextFile(strOutputFile, ForAppending, True)
objOutput.WriteLine """Date"",""File Name"",""CM Count"""
For Each objFile In objFSO.GetFolder(strFolder).Files
	If Right(LCase(objFile.Name), 4) = ".skd" Then
		strFileDay = Mid(objFile.Name, 5, 2) & "-" & MonthName(Mid(objFile.Name, 3, 2), True) & "-20" & Left(objFile.Name, 2)
		On Error Resume Next
		dteFileDay = CDate(strFileDay)
		If Err.Number = 0 Then
			On Error GoTo 0
			If dteFileDay >= dteToday Then
				Set objSKD = objFSO.OpenTextFile(objFile.Path, ForReading, False)
				strContents = objSKD.ReadAll
				objSKD.Close
				intCount = 0
				intPos = InStr(strContents, strSearchString)
				While intPos > 0
					intCount = intCount + 1
					strContents = Mid(strContents, intPos + 1)'Len(strSearchString))
					intPos = InStr(strContents, strSearchString)
				Wend
				If intCount > 0 Then
					'WScript.Echo intCount & " entries were found in " & objFile.Name
					objOutput.WriteLine Now & "," & objFile.Name & "," & intCount
				Else
					'WScript.Echo "No entries were found in " & objFile.Name
					objOutput.WriteLine Now & "," & objFile.Name & "," & intCount
				End If
			End If
		Else
			WScript.Echo "Error determining date of " & objFile.Name
			Err.Clear
			On Error GoTo 0
		End If
	End If
Next
objOutput.Close

Open in new window

Qlemo"Batchelor", Developer and EE Topic Advisor
Top Expert 2015

Commented:
May I remind you of http:#a37857240 ?
murryc
You state http:#a37857240 (as also pointed out by qlemo):
The scan would check each file for the string ,,CM, (comma comma CM comma)
Now you state http:#a37869216:
not sure where your batch looks for ,,CM1,
There's little point in providing a text file which does NOT contain any ',,CM1,'s? How are we to conclude our programs actually work as it should without proper test data? Perhaps you should have provided TWO files - one containing ',,CM1,'s in a typical scenario, and the one you provided above.

Oddly enough, there was a bug in Line 4 of my previous code where I left 'test data' ("for") where the search string (",,CM1,") should have been. Here's the corrected code:
@echo off
for /f "skip=1 tokens=1-3" %%a in ('WMIC Path Win32_LocalTime Get Day^, Month^, Year') do (
  for /f "tokens=*" %%f in ('xcopy *.skd "%temp%" /d:%%b-%%a-%%c /l ^| find /v "File(s)"') do (
    for /f "tokens=3 delims=:" %%g in ('find /c ",,CM1," "%%f"') do (
      if %%g equ 0 (
        echo DID NOT FIND any CM1 entries on schedule %%~nxf
      ) else (
        echo Found %%g CM1 entries on schedule %%~nxf
) ) ) )

Open in new window

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial