4

Is there a Linux command similar to tail where instead of specifying a number of lines you can specify a string of text, the file would be searched for that text from the last line to the first and then display all or a specified number lines after that? The content at the end of the log I'm trying to capture can vary between 0 and 10 lines so when it isn't 10 it makes the log file that I copy it to hard to understand.

From the tail man page I'm only seeing the ability to specify either lines or bytes.

  • 1
    Your question is vague... as a result, you got several answers that do different things. Specify whether you want the lines after the first occurrence or after the last one (or after the 3rd one, whatever...) – don_crissti Jul 13 '16 at 19:04

5 Answers5

4

You can use this retail command: https://github.com/mwh/retail

It supports regular expressions for starting and stopping output, so you probably want something like:

retail -r STARTPATTERN mylogfile
retail -r STARTPATTERN -u ENDPATTERN -f mylogfile

The -r option explicitly finds the last instance of the pattern, which is usually what you want.

See also: https://superuser.com/questions/270529/monitoring-a-file-until-a-string-is-found

Here's an example using an Apache error log where Apache has been restarted multiple times, using retail to extract just the final restart:

$ grep -c "Apache.*resuming normal operations" /var/web/logs/error.log
8 
$ retail -r  "Apache.*resuming normal operations" /var/web/logs/error.log
[Wed Jul  6 17:12:55.534567 2016] [mpm_prefork:notice] [pid 17965] AH00163: Apache/2.4.4 (Unix) OpenSSL/1.0.1e configured -- resuming normal operations
[Wed Jul  6 17:12:55.534582 2016] [mpm_prefork:info] [pid 17965] AH00164: Server built: Mar 26 2016 12:22:17
[Wed Jul  6 17:12:55.534598 2016] [core:notice] [pid 17965] AH00094: Command line: '/usr/local/apache2/bin/httpd'

Or you can use a regex of "(SIGTERM.* shutting down|SIGHUP.*restart)" to show everything after the last shutdown or restart attempt.

mr.spuratic
  • 9,901
4

specify a string of text and then display all lines after that

Here's some fake data to play with:

$ seq 100 > input

...and here I'm searching for the string "90" and displaying everything after it (until the $ end of the file):

$ sed -n '/90/,$p' input
90
91
92
93
94
95
96
97
98
99
100

If you want a more flexible solution, use a variable, change the sed quotes (and escape the $ from the shell, for sed):

$ t=96
$ sed -n "/$t/,\$p" input
# or
$ sed -n /$t/,\$p input
96
97
98
99
100
Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
2

The ed editor has the ability to search backwards for a preceding occurrence of a regular expression - and conveniently sets its current address to the last line of the file upon opening. So you could do

ed file
?string?,.p
q

to output lines from the last occurrence of string to the end of the file (inclusive) - or, as a one-liner

printf '?string?,.p\nq' | ed -s file
steeldriver
  • 81,074
2

If your grep has the -A flag for displaying a certain number of lines of context after each match, you can do the following:

grep -A 10 'pattern' logfile | less
Kusalananda
  • 333,661
2

Just for completeness, I'll throw in a solution using awk - while you don't need it for this specific task, it's a very powerful tool and this is the kind of problem it's good at solving.

awk '/pattern/{x=1}x{print}'

This sets the x variable when the pattern is found and prints a line whenever x is true. Note that this starts from the first occurrence of the pattern.

Random832
  • 10,666