0

I'm trying to extract the titles of events in one of my logs, which is just a text file with lots of data. The filename is eventlog-1-5-2016.txt (date is always the current date). Each line in the file is one event like this:

1-1-16(Commodore Rally)Address|Time
1-2-16(Open House)Address|Time

I just want to go through the file and extract the title in parentheses, excluding the parentheses themselves, and output the list to the console, or a text file.

I've also tried output to a txt file but I'm missing something. Can you tell me why this doesn't work:

Console:

Select-String -Path c:\log\eventlog-1-5-2016.txt -Pattern '\(([^\)]+)\)' -AllMatches |
  % { $_.Matches }

To File:

Select-string -Path c:\log\eventlog-1-5-2016.txt -Pattern '\(([^\)]+)\)' -AllMatches |
  % { $_.Matches } | { $_.Value > C:\log\results.txt

or even a better way to do this if this wrong.

Bonus question, could the path auto calculate the current date and correct the file name for easy future pasting? (not major!)

  • 3
    When asking `why this doesn't work`, please explain, in as many detail as possible, what actually happens. The input and desired outputs are described, so the question is in pretty good shape. – vonPryz Jan 13 '16 at 11:19
  • What is your output and what do you not understand about it? – ConanW Jan 13 '16 at 11:20
  • Try changing the pattern to `'(?<=\()[^\)]+)(?=\))'` since you are using `Matches`. – Wiktor Stribiżew Jan 13 '16 at 11:21
  • Thank folks, good point. There isn't any output at all. I just get >> on the screen and nothing in the output file. – Corey Duncan Jan 13 '16 at 11:49
  • Stribizhev - when i use your expression it says - Too many )'s. – Corey Duncan Jan 13 '16 at 11:54
  • The double greater-than symbols `>>` indicate that PowerShell is expecting more input. That will either be just a (typically if you've pasted several lines of code with parentheses / brackets), or a close parentheses / bracket because you have got the open/close balance wrong. – ConanW Jan 13 '16 at 15:23

2 Answers2

0

What happens is that Select-String doesn't quite do what you think it does. It will match patterns, but instead of returning the matched part, it will return you the whole matching string. Thus, the statement returns you the whole matched row instead of just substring in parenthesis. This is common a cause for confusion.

As a simple example in case of link rot,

[regex]$rx = '\(([^\)]+)\)'
cat C:\Temp\logfile.txt | % { $rx.Matches( $_ ).value }
(Commodore Rally)
(Open House)
Community
  • 1
  • 1
vonPryz
  • 22,996
  • 7
  • 54
  • 65
  • results were empty running this, though there wasn't an error. The expression itself must not match. Maybe that's my problem. – Corey Duncan Jan 13 '16 at 11:59
  • `Select-String` returns a [`MatchInfo`](https://msdn.microsoft.com/en-us/library/microsoft.powershell.commands.matchinfo.aspx) object, not just the matching string. – Ansgar Wiechers Jan 13 '16 at 16:36
0

The current date can be determined like this:

(Get-Date).ToString('d-M-yyyy')

Also, your regular expression could be simplified a little by using a non-greedy match:

`\((.+?)\)

If you want just the text between the parentheses you need the value of the captured group instead of the complete match:

$date = (Get-Date).ToString('d-M-yyyy')
Select-String -Path "C:\log\eventlog-$date.txt" -Pattern '\((.+?)\)' -AllMatches |
  ForEach-Object { $_.Matches } |
  ForEach-Object { $_.Groups[1] } |
  ForEach-Object { $_.Value } |
  Out-File 'C:\log\results.txt'

If you have PowerShell v3 or newer you could collapse the ForEach-Object statements:

Select-String -Path "C:\log\eventlog-$date.txt" -Pattern '\((.+?)\)' -AllMatches |
  ForEach-Object { $_.Matches.Groups[1].Value } |
  Out-File 'C:\log\results.txt'

Or you could use the -match operator:

Get-Content "C:\log\eventlog-$date.txt" |
  Where-Object { $_ -match '\((.+?)\)' } |
  ForEach-Object { $matches[1] } |
  Set-Content 'C:\log\results.txt'
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328