
シェルスクリプトが次のようなデータをfile.txtに追加するとします。
1...........
2...........
3.............
4.............
5..............
今、私は完全なデータではなく、5 秒以内に file.txt に追加された最新のデータをチェックできる別のスクリプトが必要です。
tail -f
完全なデータを表示するオプションがあるかどうかはわかりません。
tail -5 file.txt
-5 は行数ではなく秒数を表す数値である、といったことを理解するためです。
注: 毎回データを見逃したくないので、前回終了した場所からデータを提供する必要があります。これは重要です。
答え1
retail
はステートフル tail
各呼び出し後に inode 番号とファイル サイズを記録し、次の呼び出しでは中断したところから処理を再開します (オプションでローテーションされたファイルも処理するため、inode が記録されます)。
while true; do
retail myfile.log
sleep 5
done
retail
ファイル データ自体にタイムスタンプ (syslog 経由の場合は含まれる可能性があります) または単調に増加する ID が含まれていない限り、ファイル サイズを使用する外部状態が必要です。
ファイルが常に追加され、行ごとにフラッシュされると仮定すると、retail
データは失われません。また、高精度 (例: µs 以上の精度) でない限り、データ内のタイムスタンプを検査するよりも信頼性が高いはずです。
retail
は C で書かれており、@Ulrich Dangel の の提案に似ているようですlogtail
。これには 2 つの異なるバージョンがあるようですが、どちらも Perl で実装されていますが、どちらも使用したことはありません。
答え2
最後の5つを抽出できます行スクリプトから、tail -n 5
ファイルの最後の変更のみがタイムスタンプされますが、変更ごとにタイムスタンプは付与されません。ん秒単位で保存する場合は、自分で別途保存する必要があります。
データを定量化することができます。スクリプトの記述では、メイン ループで 1 秒ごとに起動する関数を作成します。
CSEC=`date +%S`
if [ "x$CSEC" != "x$SAVEDSEC" ] ; then
mv f4.txt f5.txt
mv f3.txt f4.txt
mv f2.txt f3.txt
mv f1.txt f2.txt
echo $BUFFER > f1.txt
BUFFER=
SAVEDSEC=$CSEC
fi
また、データを書き込む場所では、たとえば を使用するとecho
、そのデータもバッファに追加されます。
echo $DATA >file.txt
BUFFER=$BUFFER$DATA
(書き込みは 'file.txt` に書き込まれるのではなく、$BUFFER に保存されます)
この場合、スクリプトはcat f?.txt
最後の 5 秒間のデータを取得することができます。
もちろん、ロックには注意してください。あるスクリプトがディスク操作の途中で別のスクリプトを読み取ると、データが破損します。
答え3
これはまさにあなたが望む通りのことをするはずです....
#!/bin/bash
#This is the file we want to capture data from
TAILFILE=/path/to/input.txt
#This is the file we want to append to
OUTFILE=/path/to/output.txt
#How many seconds we want to tail the file
SECONDS=5
tail -F $TAILFILE >> $OUTFILE &
PID=$!
sleep $SECONDS
kill $PID