开发者

how to proceed once a file containing something in shell

开发者 https://www.devze.com 2023-03-10 19:25 出处:网络
I am writing some BASH shell script that will continuously chec开发者_如何学Pythonk a file to see if the file already contains \"Completed!\" before proceeding. (Of course, assume the file is being up

I am writing some BASH shell script that will continuously chec开发者_如何学Pythonk a file to see if the file already contains "Completed!" before proceeding. (Of course, assume the file is being updated and will eventually contain the phrase "Completed!")

I am not sure how to do this. Thank you for your help.


You can do something like:

while ! grep -q -e 'Completed!' file ; do
  sleep 1 # Or some other number of seconds
done

# Here the file contains completed


Amongst the standard utilities, tail has an option to keep reading from a file: tail -f. So filter the output of tail -f.

<some_file tail -f -n +1 | grep 'Completed!' | head -n 1 >/dev/null

There may be a delay due to buffering. You can at least reduce the delay by using fewer tools in the pipeline. In fact, some implementations of tail never buffer when you do tail -f, so the following snippet will return as soon as Completed! is written to the file.

<some_file tail -f -n +1 | sed -e '/Completed!/ q'

This assumes that the file is being appended to by some other tool. If the file is overwritten by the data-producing program after you start tail, this solution won't work. You can search the file periodically. On some systems you can call a notification mechanism to know whenever the file changes, e.g. with inotifywait under Linux.


I've done this in Kornshell:

tail -f somefile | while read line
do
    echo $line
    [[ $line == *Completed!* ]] && break
done

Note no quotes around the *Completed!* string. This allows the double square brackets to do glob pattern matching instead of string matching.

This seems to work in BASH too. However, the line with the Completed must end in a NL. Otherwise, it'll take an extra line before it breaks the loop.

You can use grep too:

tail -f somefile | while read line
do
    echo $line
    grep -iq "Completed!" && break
done

The -q parameter means quiet. If your grep doesn't take the -q parameter, you might have to pipe it to /dev/null. The -i is ignore case. Whether you want to do that is up to you.

The advantage is that you aren't doing any processing unless there's a line to read. Using sleep may mean you miss the line, or that you're processing when no line has been added to the file.


Using grep in a pipe you may turn on line buffering mode by adding the --line-buffered option!

0

精彩评论

暂无评论...
验证码 换一张
取 消