1

I've been trying to come up with a sed command to pick out a single log entry from our app server logs.

The logs are in this format:

LOG|2016-07-26_15:37:45:536|entry1|!
LOG|2016-07-26_15:37:45:536|entry2|extra data
on new line|!
LOG|2016-07-26_15:37:45:536|entry3|!
LOG|2016-07-26_15:37:45:536|entry4|!
LOG|2016-07-26_15:37:45:536|entry5|!

As you can see, some entries will be only one line and some will have multiple lines containing extra data. An entry always starts with the log type (simplified to just "LOG" above) and always ends with |!

Now this is what I have so far:

sed -n -e '/'$id'/,/|!/ p'

That works well for the multi-line log entries:

$ cat log | sed -n -e '/entry2/,/|!/ p'
LOG|2016-07-26_15:37:45:536|entry2|extra data
on new line|!

But not so well for the single-line entries, as it then displays the next-coming entry as well:

$ cat log | sed -n -e '/entry3/,/|!/ p'
LOG|2016-07-26_15:37:45:536|entry3|!
LOG|2016-07-26_15:37:45:536|entry4|!

Any ideas, on how I can modify my sed above to cover both single- and multi-line log entries?

1

You need to handle the cases separately, e.g.:

sed -n '/entry3.*[^!]$/, /|!/p; /entry3.*!/p ' log

If a line matches the id and ends with an exclamation mark, it will be printed. If a line matches the id and does not end with an exclamation mark, it marks the beginning of an address range.

3

Other way can be loop the matched line untill end of entry:

sed '/entry3|/{:a;/!$/!{n;ba;};p;};d' log

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.