使用shell脚本从最后位置读取文件

时间:2013-03-08 20:22:04

标签: shell unix file-io

我的要求是使用cron job中的shell脚本读取正在连续更新的大文件。我将读到最后一行,然后停止该过程。下次当cron作业启动时,作业应该从上次完成的位置读取。任何建议如何在shell脚本中执行此操作。

我正在使用Solaris Unix。

2 个答案:

答案 0 :(得分:1)

尝试这样(当然在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

所以主要工具有“尾巴”。问你是否有任何问题。

答案 1 :(得分:0)

已经指出的最佳方法是使用“tail -f”,但假设由于某种原因你的程序死了,你必须从头开始阅读而你不能使用“tail -f”来继续它离开了。

所以唯一的方法就是编写自己的C应用程序。它应该很容易,因为它很简单。您可以使用“ftell”找出您在数据文件中的位置。然后,您将在退出应用程序之前或每次读取之后将该结果写入其他文件(控制文件)中(如果关键是您永远不再重新处理行)。

重新启动应用程序后,您将读取该控制文件,解析该值并使用“fseek”跳转到您离开的位置。

如果某个其他应用程序截断了数据文件,您还应该获取该应用程序以删除您的控制文件。否则,您将不得不找到一些其他方式来了解该文件是新的。它可能是你读到的“fseek”大于当前的“ftell”,它表明文件比它小,但这并不能涵盖所有可能性。

您可以调查“fstat”并使用数据文件的创建时间来查看它是否比您在控制文件中保存的创建时间更新 OR 如果可以,我会在文件的第一行写一个日期/时间戳,并将其写入控制文件中。当应用程序重新启动时,如果第一行时间戳与控制文件时间戳不匹配,则从头开始读取。否则,“fseek”应该将您带到正确的位置。