You're viewing a comment by JA and its responses.

January 22, 2010, 19:45

I'm trying to extract stacktraces from log files, looking for the pattern "Exception". If a line contains "Exception", a stack trace will follow in multiple lines. If the next line begins with a timestamp entry in the format "[1/13/10 23:17:00:444 CST]", the stack trace has ended in the previous line. Additionally, I want to grab the nearest line containing a timestamp entry above the line containing the pattern "Exception". Sometimes it's on the same line and other times it's a few lines above it. How can I do write a sed command for this? Example:

[1/13/10 23:01:16:623 CST] 00000059 SystemOut     O 2010-01-13 23:01:16,623 [ORB.thread.pool : 0] INFO  
 - Exiting isAlertUpdateTimerRunning()
SystemOut     O 2010-01-13 23:01:16,623 [ORB.thread.pool : 0] INFO  com.dd.dddd.ddddddddr.ddddddr.dddddddddTriggerManager
org.hibernate.SessionException: Session is closed!
        at org.hibernate.impl.AbstractSessionImpl.errorIfClosed(
        at org.hibernate.impl.SessionImpl.reconnect(
[1/13/10 23:01:16:725 CST] 0000006e SystemOut     O 2010-01-13 23:01:16,725 [MessageListenerThreadPool : 12] INFO  com.ddconnector.cccccc.ccccccSession - Th
read[MessageListenerThreadPool : 12,5,main]

Here, I want to grab the first line, followed by the stack trace line starting "org.hibernate.SessionException" all the way until the last line of the stack trace.

Comment Responses

Robby Permalink
September 28, 2010, 00:06

This comment is a little older, but I found it as a challenge none-the-less and decided to take a crack at it & post my results in case somebody later had the same question. As a bonus (& to make it more useful for myself), it prints the line number above each exception. Here is my result:

sed -e :b -e '/Exception/!d;=;n;:a' -e '/^\[/bb' -e 'n;ba'

Brief explanation in steps:
1. :b set a label to go back to the beginning. i had to use a label, b/c i wanted to be able to go back to the beginning w/o reloading the pattern space.
2. /Exception/!d start over w/ the next line unless we find the word Exception.
3. = print out the line number
4. n print out the current line and load the next line
5. :a set another label for looping over the body of the exception
6. /^\[/bb go back to the beginning if we find a line starting with a bracket. i didn't see a need to expand the regex to match the full timestamp.
7. n;ba print out the current line and loop back to label a

Anirudh Permalink
January 31, 2016, 13:17


# sed registers:
# ...P.S. => pattern space
# ...H.S. => hold space

# timestamp entry:
# ...[mm/dd/yy HRS:MIN:SEC:MSEC TZ]
# 1 .. 12 = [1-9]\|[1][0-2]
# ......dd: 1 .. 31 = [1-9]\|[1-2][0-9]\|[3][0-1]
# ......yy: 00 .. 99 = [0-9]\{2\}
# ......HRS: 0 .. 23 = [0-9]\|[1][0-9]\|[2][0-3]
# ......MIN: 00 .. 59 = [0-5][0-9]
# ......SEC: 00 .. 59 = [0-5][0-9]
# ......MSEC: 000 .. 999 = [0-9]\{3\}
# ......TZ: [ECMP]ST



$d; H;1h; n


# status of the sed registers at this point:
# P.S. => current timepoint \n junk lines \n stack trace
# H.S. => next timepoint

# nota stack trace

# stack trace
G;h; # H.S. => current timepoint \n junk lines \n stack trace \n next timepoint
s/\n.*//; # P.S. => current timepoint

# timepoint + exception together
g; s/^\(.*\)\n.*/\1/p; # strip the next timepoint & print current timepoint alongwith stacktrace
g; s/.*\(\n\)/\1/;D; # start over with the next timepoint

# timepoint + exception NOT on same line
g; s/^\(.*\)\n.*/\1/; P

# keep chopping the lines in P.S.
# until we hit the session exception
# line at the beginning of P.S.

g; s/.*\(\n\)/\1/;D; # start over with the next timepoint

Reply To This Comment

(why do I need your e-mail?)

(Your twitter handle, if you have one.)

Type the word "linux_95": (just to make sure you're a human)

Please preview the comment before submitting to make sure it's OK.