2

Hello I have a text file containing the following info:

#[Tue Oct 25 00:00:02 2016] --- START OUTPUT
#CMD: XXX
END-->0<--
#[Tue Oct 25 00:00:57 2016] --- END
#RETURN: 1
#ELAPSED TIME (in seconds): 55

#[Tue Oct 25 00:05:01 2016] --- START OUTPUT
#CMD: XXX
END-->0<--
#[Tue Oct 25 00:05:33 2016] --- END
#RETURN: 0
#ELAPSED TIME (in seconds): 32

I want to get the --End line the Return line and the Elapsed line if its corresponding Return is > 0.

So far I have just been able to grep the Return line grep "#RETURN:" -A 1 -B 1 f.log

But how to i grep only if the Return is > 0 ?

Desired output:

#[Tue Oct 25 00:00:57 2016] --- END
#RETURN: 1
#ELAPSED TIME (in seconds): 55
  • Whats your desired output from this? – heemayl Oct 25 '16 at 7:47
  • @heemayl Please check update – Kheshav Sewnundun Oct 25 '16 at 7:49
  • So your input file has sections separated by empty lines? – Satō Katsura Oct 25 '16 at 7:52
  • @SatoKatsura not necessarily. Some are and some are not. – Kheshav Sewnundun Oct 25 '16 at 7:55
5

With awk:

awk '/END$/ {prev=$0; next}; /^#RETURN/ && $2>0 {cur=$0; pr=1; next};\
                      pr {printf "%s\n%s\n%s\n", prev, cur, $0; pr=0}' file.txt
  • /END$/ {prev=$0; next}: If the line ends with END, save it as variable prev, and go to the next line; This is the line before RETURN

  • /^#RETURN/ && $2>0 {cur=$0; pr=1; next}: If the line starts with #RETURN and the second field is greater than 0, then save the line as cur, set variable pr as 1 (true), and go to the next line

  • pr {printf "%s\n%s\n%s\n", prev, cur, $0; pr=0}: If pr is true, then print the output in desired format, and finally set pr as 0 (false)

Example:

% cat file.txt                                                                                                                   
#[Tue Oct 25 00:00:02 2016] --- START OUTPUT
#CMD: XXX
END-->0<--
#[Tue Oct 25 00:00:57 2016] --- END
#RETURN: 1
#ELAPSED TIME (in seconds): 55

#[Tue Oct 25 00:05:01 2016] --- START OUTPUT
#CMD: XXX
END-->0<--
#[Tue Oct 25 00:05:33 2016] --- END
#RETURN: 0
#ELAPSED TIME (in seconds): 32

% awk '/END$/ {prev=$0; next}; /^#RETURN/ && $2>0 {cur=$0; pr=1; next}; pr {printf "%s\n%s\n%s\n", prev, cur, $0; pr=0}' file.txt
#[Tue Oct 25 00:00:57 2016] --- END
#RETURN: 1
#ELAPSED TIME (in seconds): 55
| improve this answer | |
  • It's a nice algorithm and I love awk but isn't it a job more suited for grep since the lines are contiguous ? – Valentin B. Oct 25 '16 at 8:04
  • @ValentinB. If the file contents are literal, then yes. Although your approach can be made more compact: 1) egrep is not needed as there is no ERE token in your pattern 2) Use -C1 instead of mentioning both -A and -B as the lien counts are the same. Just do: grep -C1 'RETURN: [1-9][0-9]*' file.txt – heemayl Oct 25 '16 at 8:07
  • Well thank you for the input, I will edit my post accordingly! Had not thought that this was not an extended regex, and had forgotten about the context option of grep. Yours is indeed more robust but I will leave mine as a "simple" alternative. – Valentin B. Oct 25 '16 at 8:13
0

you can try this;

awk -F: '/#RETURN:/ && $2 > 0 { getline; print $0}' test

Eg;

user@host:/tmp$ awk -F: '/#RETURN:/ && $2 > 0 { getline; print $0}' test
#ELAPSED TIME (in seconds): 55
| improve this answer | |
0

You should use regular expressions in your grep:

 grep -C1 'RETURN: [1-9][0-9]*' input.txt

That regexp should catch any (positive) number that is not a single 0 (or does not start with a 0).

| improve this answer | |

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.