0

I'm trying to get full error with line from following example:

date time somemethod EXC somenumber sometext  R:System.NullReferenceException: Object reference not set to an instance of an object.
   at sometext in somepath .cs:line somenumber System.NullReferenceException: Object reference not set to an instance of an object.
   at sometext in Somepath .cs:line somenumber 

From that, I'd like to get everything after EXC up to cs:line somenumber.

01/01/01 date (mode) (status) (somenumber) (name+error), right here there's usually a new line which continues with error message, which ends on characters cs:line (number).

I managed to get error message as it always starts with EXC (so regex is EXC .*, however im unable to get full message with code. I have access to PowerShell 2.0 only, I'm using following formula:

$Filecontent = [io.file]::Readalltext("path to file")
$filecontent | select-string 'EXC .*' -allmatches |
  foreach {$_.Matches} | Foreach {$_.Value} > errors.txt

What I need is to get full error with line number but I have problem with proper regular expression. I do not care about the date,time,mode, regex should get EXC status and take full message with line.

After using regex 'EXC .*\n.*cs:line [0-9]{0,99}' it finds me those messages that after one line are finished with error message, however, sometimes theres more next lines that I'd like to capture as well. Any ideas?

1
  • typo in formula, fixed:$Filecontent = [io.file]::Readalltext("path to file") $filecontent | select-string 'EXC .' -allmatches | foreach {$_.Matches} | Foreach {$_.Value} > errors.txt Commented Nov 30, 2015 at 12:00

1 Answer 1

3

If you define an error (stack trace) as

  • begins with a non-whitespace character in column 1
  • spans multiple lines
  • every additional line that belongs to the error is indented by 3 spaces

then the regex to capture such a block looks like follows:

(?m)^\S.*(\s*^   \S.*)+

After you have retrieved a complete stack trace block with that you can pick out line numbers in a second step using something like this:

at (.*?) in (.*?):line (\d+)

The expression breaks down as:

(?m)         # inline flag: multiline mode
^            # start-of-line
\S           # a non-whitespace character
.*           # anything up to the end of the line
(            # group 1
  \s*        #   any number of whitespace (this matches newline character)
  ^          #   start-of-line
             #   3 spaces
  \S         #   a non-whitespace character
  .*         #   anything up to the end of the line
)+           # end of group 1, repeat at least once

Compare: https://regex101.com/r/rW1hD6/1

Sign up to request clarification or add additional context in comments.

8 Comments

I'd like to define it as follows: -Begins with EXC and one whitespace -spans multiple lines -ends with cs:line (number up to four digits)
My expression captures a superset of those. Make it more specific if you need that, for example by putting EXC into the appropriate spot. Or by letting Select-String get all stack traces first and then pipe them through Where-Object. There are many ways to do this.
uhm, im probably doing something wrong, but when I use '^\S.*(\s*^ \S.*)+' its not retrieving anything. inside () there are 3 spaces as I understood ?
Yes, three spaces. Did you notice the "multiline" part? I don't think Select-String has a switch for that, but you can enable it in the regex itself by prepending it with (?m), like (?m)^\S.*(\s*^ \S.*)+. That switch is crucial, otherwise you can't have multiple ^ in the same expression.
Great, many thanks Tomalak. Could you please explain to me this regex as im still learning and all I found is \s is for whitespace and \S is for not white space, and its kind of unclear how it does the job, but this formula: select-string '(?m)^\S.*(\s*^ \S.*)+' -allmatches | foreach { {$_.Matches} | foreach {$_.Value} > file.txt gets the job done(all types of errors with all new lines and code.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.