Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do a tail -F until matching a pattern

Tags:

shell

sed

tail

awk

tcl

I want to do a tail -F on a file until matching a pattern. I found a way using awk, but IMHO my command is not really clean. The problem is that I need to do it in only one line, because of some limitations.

tail -n +0 -F /tmp/foo | \ awk -W interactive '{if ($1 == "EOF") exit; print} END {system("echo EOF >> /tmp/foo")}' 

The tail will block until EOF appears in the file. It works pretty well. The END block is mandatory because awk's exit does not exit right away. It makes awk to eval the END block before quitting. The END block hangs on a read call (because of tail), so the last thing I need to do, is to write another line in the file to force tail to exit.

Does someone know a better way to do that?

like image 605
Sam Alba Avatar asked Feb 17 '11 02:02

Sam Alba


People also ask

Which command is used for matching the patterns?

The grep command can search for a string in groups of files. When it finds a pattern that matches in more than one file, it prints the name of the file, followed by a colon, then the line matching the pattern.

How do I print lines between two patterns?

The sed command will, by default, print the pattern space at the end of each cycle. However, in this example, we only want to ask sed to print the lines we need. Therefore, we've used the -n option to prevent the sed command from printing the pattern space. Instead, we'll control the output using the p command.

How do you grep a line before a match?

To also show you the lines before your matches, you can add -B to your grep. The -B 4 tells grep to also show the 4 lines before the match. Alternatively, to show the log lines that match after the keyword, use the -A parameter. In this example, it will tell grep to also show the 2 lines after the match.


2 Answers

Use tail's --pid option and tail will stop when the shell dies. No need to add extra to the tailed file.

sh -c 'tail -n +0 --pid=$$ -f /tmp/foo | { sed "/EOF/ q" && kill $$ ;}' 
like image 120
Greg Barrett Avatar answered Nov 04 '22 16:11

Greg Barrett


Try this:

sh -c 'tail -n +0 -f /tmp/foo | { sed "/EOF/ q" && kill $$ ;}' 

The whole command-line will exit as soon as the "EOF" string is seen in /tmp/foo.

There is one side-effect: the tail process will be left running (in the background) until anything is written to /tmp/foo.

like image 44
jpetazzo Avatar answered Nov 04 '22 17:11

jpetazzo