我的要求是读取大文件,该文件使用cron作业的shell脚本不断更新。我会阅读,直到最后可用的行,然后停止该过程。下次当cron作业开始时,应该从上次完成的位置读取作业。任何建议如何在shell脚本中执行此操作。使用shell脚本从最后位置读取文件
我正在使用Solaris Unix。
我的要求是读取大文件,该文件使用cron作业的shell脚本不断更新。我会阅读,直到最后可用的行,然后停止该过程。下次当cron作业开始时,应该从上次完成的位置读取作业。任何建议如何在shell脚本中执行此操作。使用shell脚本从最后位置读取文件
我正在使用Solaris Unix。
已经指出的最好的方法是使用“tail -f”,但假设由于某种原因你的程序死了,你将不得不从头开始阅读,并且你不能使用“tail -f”继续它离开的地方。
所以唯一的方法是编写自己的C应用程序。它应该很容易,因为它很简单。您可以使用“ftell”来找出您在数据文件中的位置。然后,您将在退出应用程序之前或在每次读取之后(如果重要的是您再也不重新处理一行)将结果写入其他文件(控制文件)。
重新启动应用程序后,您会读取该控制文件,解析该值并使用“fseek”跳转您离开的位置。
如果数据文件被某些其他应用程序截断,则还应该获取该应用程序以删除控制文件。否则,你将不得不寻找一些其他方式知道该文件是新的。它可能是你读的“fseek”比当前的“ftell”更大,这表明文件比它小,但这不会涵盖所有可能性。
你可以调查“FSTAT”,并使用数据文件的创建时间,看它是否比你会保存在控制文件OR,如果你能创建时间较新的,我会写一个日期/时间戳记在文件的第一行,并将其写入控制文件中。当应用程序重新启动时,如果第一行时间戳与控制文件时间戳不匹配,则从头开始读取。否则,“fseek”会将您带到正确的位置。
尝试像这样的(当然在cron增加它):
#!/bin/bash
#STAT_FILE=/tmp/stat.tmp
PREV_LINE_STAT=/tmp/prev_last_line.tmp
LINE=$(cat log | wc -l)
LOG=/tmp/log.tmp
if [ -f $PREV_LINE_STAT ]
then
PREV_LINE=$(cat $PREV_LINE_STAT)
else
PREV_LINE=0
fi
declare -i LINE_RANGE
LINE_RANGE=$LINE-$PREV_LINE
if [ $LINE_RANGE -lt 0 ]
then
LINE_RANGE=$LINE
fi
tail -n $LINE_RANGE log > $LOG
COUNT1=$(grep any_word $LOG |wc -l)
echo "-------------------
LINE_RANGE is $LINE_RANGE
-------------------
number of words
$COUNT1" > test.txt
echo $LINE > $PREV_LINE_STAT
cat test.txt
所以主要的工具有“尾巴”。询问我是否有任何问题。
'tail -n'需要从头开始读取文件;由于文件很大,这可能相当耗时。因此,'tail -c'(正如Barmar上面所建议的)可能会更好。 – Armali 2014-06-05 06:36:04
保存旧的文件大小,然后使用'tail -c + $ filesize logfile'。 – Barmar 2013-03-08 20:26:27
为什么“cron”使事情变得复杂?启动一个进程并将其读到文件末尾,然后休眠一段时间(保持文件打开)。当它醒来时,从它进入睡眠状态时的文件位置读取更多数据。 – 2013-03-08 20:56:52
或管'tail -f',它可以自动执行“读取,休眠”循环。 – Barmar 2013-03-08 21:02:12