Author Posts

November 1, 2013 at 12:58 am

Hi there,

I have a very large text file, from which I extract some strings and store them in a variable $a.
That variable $a looks like:
2013/09/20 16:45:59.285 [009] Collect finished
2013/09/23 08:17:58.678 [009] *** Collect CMI commands for system
2013/09/23 08:18:03.561 [009] Collect finished
2013/09/23 08:19:39.878 [023] Collect finished
2013/09/24 08:16:42.238 [009] *** Collect CMI commands for system
2013/09/24 08:16:49.430 [009] Collect finished
2013/09/24 08:17:53.052 [009] *** Collect CMI commands for system
2013/09/24 08:17:57.058 [009] Collect finished
2013/09/24 08:18:20.987 [023] Collect finished
2013/09/25 08:27:50.636 [009] *** Collect CMI commands for system
2013/09/25 08:27:59.528 [009] Collect finished
2013/09/25 08:45:12.290 [009] *** Collect CMI commands for system
2013/09/25 08:45:17.142 [009] Collect finished
2013/09/25 08:47:17.060 [023] Collect finished

Now I would like to somehow select only the lines containing the text "Collect CMI commands for system" together with the very next line.
So my goal is to obtain this:
2013/09/23 08:17:58.678 [009] *** Collect CMI commands for system
2013/09/23 08:18:03.561 [009] Collect finished
2013/09/24 08:16:42.238 [009] *** Collect CMI commands for system
2013/09/24 08:16:49.430 [009] Collect finished
2013/09/24 08:17:53.052 [009] *** Collect CMI commands for system
2013/09/24 08:17:57.058 [009] Collect finished
2013/09/25 08:27:50.636 [009] *** Collect CMI commands for system
2013/09/25 08:27:59.528 [009] Collect finished
2013/09/25 08:45:12.290 [009] *** Collect CMI commands for system
2013/09/25 08:45:17.142 [009] Collect finished

I tried regular expressions, but I can't figure out how to use the carriage return character.
This is what I tried:
$regex = ".*Collect CMI commands for system.*(\r.*)"
$a -match $regex

That regular expression should return the line containing the specific text and its consecutive line.

But this doesn't return anything...

Well, then I thought that this text is not really a string, but it's an array. Still, how can I filter the array to obtain the same text I already mentioned?

Thank you!

November 1, 2013 at 1:17 am

Alright, I did some further troubleshooting and realized this is indeed an array.
So, how can I get the index of an element containing "Collect CMI commands for system"?
My way of thinking is: Get the index of that element, add +1 to the index and return both elements.
I tried already:
[array]::IndexOf($a,"*Collect finished*")
but this returns -1 (maybe because there are multiple such lines?)

November 1, 2013 at 2:48 am

I think I figured it out:
So, $a was my array of lines.
$regex = ".*Collect CMI commands for system.*"
$b = 0..($a.Count – 1) | where {$a[$_] -match $regex}
foreach ($item in $b) {$a[$item],$a[$item + 1]}

This will return me exactly what I wanted:
2013/09/23 08:17:58.678 [009] *** Collect CMI commands for system
2013/09/23 08:18:03.561 [009] Collect finished
2013/09/24 08:16:42.238 [009] *** Collect CMI commands for system
2013/09/24 08:16:49.430 [009] Collect finished
2013/09/24 08:17:53.052 [009] *** Collect CMI commands for system
2013/09/24 08:17:57.058 [009] Collect finished
2013/09/25 08:27:50.636 [009] *** Collect CMI commands for system
2013/09/25 08:27:59.528 [009] Collect finished
........................................

Thank you guys for your time!

November 1, 2013 at 3:35 am

Another way you can accomplish this is with the -Context parameter to Select-String. For example:

$a | Select-String -Pattern '.*Collect CMI Commands for system.*' -Context 1 |
ForEach-Object {
    $_.Matches[0].ToString()
    $_.Context.PostContext[0]
}

November 1, 2013 at 2:22 pm

Here's a regex solution:


#PS E:\temp> $a = gc .\data-cmi.txt # the example date pasted into a file
#PS E:\temp> $a = $a -join "`n" # create a one-line string from the array
#PS E:\temp> $a = $a -replace '\r', '' # just to be safe, they're not needed anyway
#PS E:\temp> [regex]::Matches($a, '([^\n]+ Collect CMI commands for system[^\n]*\n[^\n]+)') | %{ $_.Value }
#2013/09/23 08:17:58.678 [009] *** Collect CMI commands for system
#2013/09/23 08:18:03.561 [009] Collect finished
#2013/09/24 08:16:42.238 [009] *** Collect CMI commands for system
#2013/09/24 08:16:49.430 [009] Collect finished
#2013/09/24 08:17:53.052 [009] *** Collect CMI commands for system
#2013/09/24 08:17:57.058 [009] Collect finished
#2013/09/25 08:27:50.636 [009] *** Collect CMI commands for system
#2013/09/25 08:27:59.528 [009] Collect finished
#2013/09/25 08:45:12.290 [009] *** Collect CMI commands for system
#2013/09/25 08:45:17.142 [009] Collect finished

November 2, 2013 at 1:03 am

thank you all! your suggestions are more than welcome!