Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I use the following command to parse a log file for a particular string. Then I search backwards in the log to find the data I really want. The problem as in the example below, I am only going back 50 lines. It is unknown if the text I am looking for will be 5 lines back, 200 lines back or more. Is there a way to search through a log file for a particular string, and when that string is found, to then search backwards through the log to find a 2nd string despite not knowing how far back the 2nd string is located. Also there could be multiple occurrence of the 1st string. So for for every instance of the 1st string, I want to be able to search backwards to collect the data from the second string.

grep -B50 "Server returned HTTP response code: 500 for URL:" LCSoap_8.log | \
tac | grep -P -o '(?<=qualified-src-dn=).*(?=src-dn)'
share|improve this question
    
1  
@steeldriver, no, they are different questions, though similar. –  Stéphane Chazelas Aug 15 at 14:27

2 Answers 2

up vote 2 down vote accepted
tac LCSoap_8.log | sed -n '
  /Server returned HTTP response code: 500 for URL:/,/qualified-src-dn=.*src-dn/!d
  s/.*qualified-src-dn=\(.*\)src-dn.*/\1/p'

or to reuse your grep:

tac LCSoap_8.log | sed '
  /Server returned HTTP response code: 500 for URL:/,/qualified-src-dn=.*src-dn/!d' |
  grep -Po '(?<=qualified-src-dn=).*(?=src-dn)'

sed '/A/,B/!d' d̲eletes every line except (!̲) those from to the next after that.

share|improve this answer
    
Thank you! I went with the bottom one. –  apropos Aug 18 at 12:56

Here is a possible PCRE-based solution based on a similar question Search a pattern and print preceding lines starting with another pattern

grep -zPo '.*abc.*(?=(?s)(?(?!abc).)*?xyz)' file

will output the last line containing abc that occurs before each instance of xyz

e.g. given a file

1 abc
2 abc
3 abc
4 abc
5 abc
6 bcd
7 cde
8 def
9 xyz
10 xyz

then

$ grep -zPo '.*abc.*(?=(?s)(?(?!abc).)*?xyz)' file
5 abc
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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