We are running solaris 10 at work. What I'd like to do is find the line previous to another line.

Real live example. I can find out that some of our requests are timing out with the following query.

grep timeout log.log.

This gives me something similar to:

2010-11-30 20:59:57,495 ERROR [ - 342E15CB9651927BE715780FC40DEC53 - 3675058] Send Call (AbstractEngineServlet.java:288) > - Merchant error HTTPS Comms found. Merchant Trans Id: 22283845800 The host did not accept the connection within timeout of 60000 ms

In the log files though but it may be several lines previous we log about to call

2010-11-30 20:56:57,495 INFO [ - 342E15CB9651927BE715780FC40DEC53 - 3675058] about to call http://www.example.com

So what I would like to do is identify all timeouts and then identify all the "about to call" lines which are directly previous and have the same IP address or session.

In the above example it would be finding the previous row containing "342E15CB9651927BE715780FC40DEC53" is this possible with the standard shell tools?

3 Answers 3


This looks like a job for awk. Assuming your logs are sufficiently regular (in particular I'm extracting the session cookie as the 6th field):

<foo.log awk '
  /about to call/ {target[$6]=$0;}
  /AbstractEngineServlet.*timeout/ {print target[$6]; print;}
  • I think I can work with this. I won't have an answer to whether it worked straight away (I simplified my question).
    – Wes
    Nov 30, 2010 at 22:20
  • Works great. I'd like to understand this where can I find a decent resource on AWK (or should this be a seperate question)?
    – Wes
    Dec 1, 2010 at 21:18
  • 1
    @Wes: There's A, W and K's classic book, and a more recent O'Reilly book. The GNU awk manual is also readable (it teaches GNU awk, not portable awk, however). Or you can learn by example from unix forums plus reference manuals. Dec 2, 2010 at 0:56
for i in `grep timeout log.txt|awk '{print $6}'`;
  grep $i log.txt;
  echo "-----------------";

Untested, but something like

#!/usr/bin/env perl

my %lastline;

while (<>) {
    if (/\b([[:xdigit:]]{32})\b/) {
        if (/INFO/) {
            $lastline{$1} = $_;
        elsif (/ERROR/) {
            print delete $lastline{$1} if exists $lastline{$1};

probably works.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .