我正在编写一些BASH shell脚本,它将不断检查文件以查看文件是否已包含“已完成!”在继续之前。 (当然,假设文件正在更新,最终将包含短语“已完成!”)
我不知道该怎么做。谢谢你的帮助。
答案 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
选项来启用线路缓冲模式!