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
  • 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...) Jul 13, 2016 at 19:04

5 Answers 5

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
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.

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
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
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.

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.