1.

Solve : Findstr and Find patterns?

Answer»

Hi there,
What I want to do is perform a search on a .txt log file for two different pieces of information :
1. "528"
2. "user name = username2"

After I have SEARCHED for "538" AND "user name = username2" these lines must be directed to another text file.

I am aware about how to find one string, but not two in another area.
Does anyone have any ideas about this?

THANKS,
Laura
you can use vbscript

Code: [Select]Set objFS=CreateObject("Scripting.FileSystemObject")
Set objArgs = WScript.Arguments
strFile = objArgs(0)
Set objFile = objFS.OpenTextFile(strFile)
Do Until objFile.AtEndOfStream
strLine = objFile.ReadLine
If InStr(strLine,"528") > 0 Then
flag=1
str528 = strLine
End If
If flag=1 And InStr(strLine,"user name = username2")>0 Then
WScript.Echo str528
WScript.Echo strLine
flag=0
End If
Loop


example
Code: [Select]
C:\test>more file
this is a line
1. 528
this is another line
2. user name = username2
this is end line

C:\test>cscript /nologo test.vbs file
1. 528
2. user name = username2

Code: [Select]@echo off
set filename1=log1.txt
set filename2=log2.txt
set string1=528
set string2=user name = username2
type "%filename1%" | find "%string1%">nul && (
type "%filename1%" | find "%string2%">nul && (
echo %string1% and %string2% found in %filename1%>"%filename2%"
)
)
Quote from: Salmon Trout on November 27, 2009, 01:12:41 AM

Code: [Select]@echo off
set filename1=log1.txt
set filename2=log2.txt
set string1=528
set string2=user name = username2
type "%filename1%" | find "%string1%">nul && (
type "%filename1%" | find "%string2%">nul && (
echo %string1% and %string2% found in %filename1%>"%filename2%"
)
)
if there are 1000 "528"s in log1.txt, the code is going to open the file 1000 times to find "username". am i correct to SAY that? A more efficient method is to go through the file once,
1) check for 528, set a flag to indicate found
2) the save the line that contains 528 in memory(variable),
3) check for "username" and if found, print it together with the saved variable.

Quote from: gh0std0g74 on November 27, 2009, 02:45:09 AM
if there are 1000 "528"s in log1.txt, the code is going to open the file 1000 times to find "username". am i correct to say that?

Log1.txt is opened either once or twice. Firstly, the output of type is piped to find and the output of find (if any) is redirected to the null device. If string1 is found at least once then the errorlevel is set zero on COMPLETION and the command on the (logical) right hand side of the && operator is executed, opening log1.txt for the second time. Finally if the errorlevel from the second pass is zero, the output to file is carried out.

I just THOUGHT the nested &&s were elegant. Bad habit, I know!

Quote from: gd74
A more efficient method is to go through the file once,
1) check for 528, set a flag to indicate found
2) the save the line that contains 528 in memory(variable),
3) check for "username" and if found, print it together with the saved variable.

I agreed until I did some timing tests. See below.

Code: [Select]set filename1=log1.txt
set filename2=log2.txt
set string1=528
set string2=user name = username2
set flag1=0
set flag2=0
for /f "delims=" %%A in ( ' type "%filename1%" ' ) do (
echo %%A | find "%string1%">nul && set flag1=1
echo %%A | find "%string2%">nul && set flag2=1
)
set /a flagT=%flag1%+%flag2%
if %flagT% equ 2 echo Strings "%string1%" and "%string2%" found in file "%filename1%">"%filename2%"

In fact, you can do all the work in one line, at the cost of opening the input file twice.

Code: [Select]@echo off
set filename1=log1.txt
set filename2=log2.txt
if exist "%filename2%" del "%filename2%"
set string1=528
set string2=user name = username2
type "%filename1%" | find "%string1%">nul && type "%filename1%" | find "%string2%">nul && echo "%string1%" and "%string2%" found in "%filename1%" > %filename2%

I am going to do some timing tests with a 1000 line x 80 char Loret Ipsum text file. Search string 1 is inserted into line 250 and search string 2 is inserted into line 750.

Results:

1 pass using FOR loop and flag variables: 4 mins 32 sec
2 pass using type | find>nul && type | find>nul && echo Positive Result>file : 0.33 sec

These results were so surprising that I have repeated the test several times. The result: 1 pass around 4 minutes, 2 pass around one third of a second.




that's because for every line, its piping to 2 find's. if the use of "find" or "findstr" can be reduced, the better. I am tending toward the use of the if statement. if string1== string2... Isn't there a way to test whether a substring exists using if (or cmd.exe in built commands?) If you do most of this in cmd.exe instead of calling external commands, i think it will be faster.Quote from: gh0std0g74 on November 27, 2009, 07:28:21 AM
If you do most of this in cmd.exe instead of calling external commands, i think it will be faster.

Well, I think 3000 lines a second isn't bad for a first attempt.

Thanks alot guys I'm a newbie with all of this and have to do reports on a security log.. hence all my posts
You've been great!
Laura


Discussion

No Comment Found