简体   繁体   中英

How do I search for a string with 2 patterns in powershell?

I'm trying to search log files for a string that must contain 2 patterns, the word "down" and a specific date, but they are not next to each other in the string. Everything I've tried so far has been either down or the date but not necessarily both. Like I said I want the strings that ONLY have both. How would I go about doing this? Preferably in the powershell command line?

Heres a link to technet, a microsoft blog, on how to do that. powershell documentation

use -pattern to delimit the pattern. -pattern uses string or a regex for the pattern

you need to also add the -path to your log file

C:/> select-string -path path/to/file/logname.log -pattern "text or regex"

if you have more than 1 log use this

C:/> select-string -path path/to/file/*.log -pattern "text or regex"

Well, there's a couple ways to go about this that I know of. The RegEx way, and the other way. First the simple way... (I don't know your date, so I'm using 5/4/13)

GC $LogFile | ?{ $_ -match "down" -and $_ -match "5/4/13" }

Then with RegEx you could do something like:

GC $LogFile | ?{ $_ -match "(down).*?(5/4/13)" }

So that looks for the word "down" followed by any number of characters, followed by "5/4/13". The only possibly confusing bit there is the .*? part. The dot in regex matches any character except a New Line or Carriage Return character. The * mean zero or more of those characters, and the ? means that it won't take more than is needed before the next match item (5/14/13 in this case). If the date comes first you reverse the order. If you don't know the order, well, then use option 1 or find somebody better at RegEx than me. It can be done without knowing the order, but I can't remember how since I have never used that myself.

Edit: Ok, I found the RegEx I was thinking of, because Frode's comment made me realize that it is something I should know because it's better in general, and it bugged me not knowing. So...

Updated RegEx option! This will search for the word "down", and the date "5/4/13" no matter which order they are in, and if it finds one it will only look for the other as its second match. So it'll match "down <other text> 5/4/13" and "5/4/13 <other text> down" .

-match "(down|(5/4/13)).*?(?(2)down|5/4/13)"

See these examples that I ran it against:

PS C:\> "5/4/13 - SQLSrvr17 went down" -match "(down|(5/4/13)).*?(?(2)down|5/4/13)"
True

PS C:\> "There was downtime on server2 on 5/4/13" -match "(down|(5/4/13)).*?(?(2)down|5/4/13)"
True

PS C:\> "The downtime was due to server 3 being down" -match "(down|(5/4/13)).*?(?(2)down|5/4/13)"
False

PS C:\> "5/4/13 is 5/4/13" -match "(down|(5/4/13)).*?(?(2)down|5/4/13)"
False

Usage for a log file would be:

GC Logfile.log | ?{ $_  -match "(down|(5/4/13)).*?(?(2)down|5/4/13)" }

If that log file contained the 4 lines I tested against the result would be:

5/4/13 - SQLSrvr17 went down
There was downtime on server2 on 5/4/13

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM