1

我的要求是读取一个使用 cron 作业中的 shell 脚本不断更新的大文件。我会读到最后一行,然后停止这个过程。下次 cron 作业开始时,作业应该从上次完成的位置读取。任何建议如何在 shell 脚本中执行此操作。

我正在使用 Solaris Unix。

4

2 回答 2

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

所以这里的主要工具是“尾巴”。问我是否有任何问题。

于 2013-12-30T07:59:59.733 回答
0

如前所述,最好的方法是使用“tail -f”,但假设由于某种原因你的程序死了,你必须从头开始阅读,你不能使用“tail -f”从中断的地方继续.

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

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

如果数据文件被其他应用程序截断,您还应该让该应用程序删除您的控制文件。否则,您将不得不找到其他方法来知道该文件是新文件。可能是您读取的“fseek”大于当前的“ftell”,这表明文件比原来小,但这并不能涵盖所有可能性。

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

于 2013-03-14T20:04:05.173 回答