如何在shell中包含某些内容的文件中继续

时间:2011-06-05 20:27:41

标签: bash

我正在编写一些BASH shell脚本,它将不断检查文件以查看文件是否已包含“已完成!”在继续之前。 (当然,假设文件正在更新,最终将包含短语“已完成!”)

我不知道该怎么做。谢谢你的帮助。

4 个答案:

答案 0 :(得分:4)

您可以执行以下操作:

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

# Here the file contains completed

答案 1 :(得分:1)

在标准实用程序中,tail可以选择继续读取文件:tail -f。因此,请过滤tail -f的输出。

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

由于缓冲可能会有延迟。您可以通过在管道中使用更少的工具来至少减少延迟。事实上,tail的某些实现从未在tail -f执行时缓冲,因此只要将Completed!写入文件,就会返回以下代码段。

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

这假定该文件正被其他工具追加。如果在启动tail后数据生成程序覆盖文件,则此解决方案将无效。你可以search the file periodically。在某些系统上,您可以调用通知机制来了解文件何时更改,例如在Linux下使用inotifywait

答案 2 :(得分:0)

我在Kornshell做过这个:

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

请注意 * Completed!* 字符串周围没有引号。这允许双方括号进行glob模式匹配而不是字符串匹配。

这似乎也适用于BASH。但是,Completed的行必须以NL结尾。否则,在它打破循环之前需要额外的一行。

您也可以使用grep

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

-q参数表示安静。如果您的grep未使用-q参数,则可能需要将其传递给/dev/null-i是忽略大小写。您是否愿意这样做取决于您。

优点是除非有读取行,否则您不进行任何处理。使用sleep可能意味着您错过了该行,或者当没有行添加到该文件时您正在处理该行。

答案 3 :(得分:0)

在管道中使用grep,您可以通过添加--line-buffered选项来启用线路缓冲模式!