4
$\begingroup$

I use grep to find the string "Converged?" with the terminal in several folders to read the output from my gaussian calculations.

My command is

grep -r -i -A4 Converged?

What I get as output is in minimal example this:

start_struc.log:         Item               Value     Threshold  Converged?
start_struc.log- Maximum Force            0.000022     0.000450     YES
start_struc.log- RMS     Force            0.000005     0.000300     YES
start_struc.log- Maximum Displacement     0.010813     0.001800     NO 
start_struc.log- RMS     Displacement     0.002734     0.001200     NO 
--
start_struc.log:         Item               Value     Threshold  Converged?
start_struc.log- Maximum Force            0.000001     0.000450     YES
start_struc.log- RMS     Force            0.000000     0.000300     YES
start_struc.log- Maximum Displacement     0.001210     0.001800     YES
start_struc.log- RMS     Displacement     0.000312     0.001200     YES

But I just want the last time grep finds Converged? with the next four Lines. I looked up different internet forums and the manual of grep but I think I did not find a flag I can use. Because the problem is, I get up to 50 hits before and I don't want to print them out in terminal. Has someone an idea or search for the convergence the same way?

Thanks in advance

$\endgroup$

2 Answers 2

9
$\begingroup$

I think this requires piping, see these ServerFault or StackOverFlow questions. For a single file, the two main approaches would be using tail or tac. I tend to use the tail approach most myself, as I find it easier to remember or to just slap onto the end of a preceding grep statement.

  • grep -i -A4 Converged? file | tail

will print the last 10 lines from grep's output. To specify it further, make it print only the last 5 lines corresponding to the last entry:

grep -i -A4 Converged? file | tail -n 5

  • Alternatively, use tac to "cat" a file backwards, and then grep -m 1 to print only the first match:

tac file | grep -i -m 1 -B4 Converged? | tac

Again, tac outputs the file backwards so we need to use -B4 instead of -A4 to get the additional lines. The final pipe to tac reverses the line order again, to match that in the file.

  • To do this for many files, you can use a for loop, either in a shell script or as a one-liner:

for a in files; do tac $a | grep -i -B4 -m 1 Converged? | tac; done

where you need to replace "files" by an appropriate path to the different files.

$\endgroup$
0
$\begingroup$

You could also use Ex.

ex file <<< '?Converged?,+4p'

Or to print until the end of the file instead of just 4 lines,

ex file <<< '?Converged?,$p'
$\endgroup$

You must log in to answer this question.

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