nullバイトで埋められた10Mbファイルがあります。プログラムはファイルにアクセスし、ファイルの最後までゼロを特定の文字列に変更します。
を試しましたが、tail -F | grep wanted_text | grep -v "unwanted_text"
変更を監視しません。ゼロで埋められたファイルではなく、プレーンテキストファイルでのみ機能します。
すべてのヌルバイトは、ファイルの最後まで改行で区切られた行に置き換えられます。ファイルがいっぱいになると名前が変更され、新しいファイルが作成されます。
それでは、nullバイトで埋められたファイルの変更をどのように監視し、出力をフィルタリングできますか?
ベストアンサー1
以下は、NULパディングファイルのtailコマンドを偽造するために必要なものと同様のReaderスクリプトです。ファイルの変更を確認し(ナノ秒単位のタイムスタンプを含む完全なls -l出力を比較して)、バッチに追加された内容を報告します。起動時にファイルにすでに存在する行は報告せず、実行時に追加された行のみを報告します。
小切手の無駄を避けるために、2つの速度で実行されます。追加が検出されたら、1.0秒後にもう一度やり直してください。ループに追加が表示されない場合は、5秒後に再試行します(5はプロセスのパラメータです)。
#! /bin/bash
#: Reader: tail -f a file which is pre-formatted with many trailing NUL characters.
#### Implement the User Requirement.
function Reader {
local RUN="${1:-60}" SLEEP="${2:-5}" FILE="${3:-/dev/null}"
local AWK='''
BEGIN { NUL = "\000"; }
function Tick (Local, cmd, ts) {
cmd = "date \047+%s\047";
cmd | getline ts; close (cmd); return (ts);
}
function TS (Local, cmd, ts) {
cmd = "date \047+%H:%M:%S.%N\047";
cmd | getline ts; close (cmd); return (ts);
}
function Wait (secs) {
system (sprintf ("sleep %s", secs));
}
function isChange (Local, cmd, tx) {
cmd = sprintf ("ls 2>&1 -l --full-time \047%s\047", Fn);
cmd | getline tx; close (cmd);
if (tsFile == tx) return (0);
tsFile = tx;
if (index (tx, "\047")) {
if (fSt != "B") { fSt = "B"; printf ("%s: No file: %s\n", TS( ), Fn); }
} else {
if (fSt != "G") { fSt = "G"; printf ("%s: Reading: %s\n", TS( ), Fn); }
}
return (1);
}
function atNul (buf, Local, j) {
j = index (buf, NUL);
return ((j > 0) ? j : 1 + length (buf));
}
function List (tx, Local, ts, X, j) {
sub ("\012$", "", tx); split (tx, X, "\012");
ts = TS( );
for (j = 1; j in X; ++j) {
printf ("%s %3d :%s:\n", ts, length (X[j]), X[j]);
}
}
function Monitor (Local, rs, tk, Buf, Now, End) {
printf ("%s: READER Begins\n", TS( ));
tk = Tick( ); Expired = tk + Run;
Now = -1;
while (Tick( ) <= Expired) {
if (! isChange( )) { Wait( Sleep); continue; }
rs = RS; RS = "\000";
Buf = ""; getline Buf < Fn; close (Fn);
RS = rs;
if (Now < 0) Now = atNul( Buf);
End = atNul( Buf);
List( substr (Buf, Now, End - Now));
Now = End;
Wait( 1.0);
}
printf ("%s: READER Exits\n", TS( ));
}
NR == 1 { Run = $0; next; }
NR == 2 { Sleep = $0; next; }
NR == 3 { Fn = $0; }
END { Monitor( Fn); }
'''
{
echo "${RUN}";
echo "${SLEEP}";
echo "${FILE}";
} | awk -f <( echo "${AWK}" )
}
#### Script Body Starts Here.
Reader 40 5 "./myNullFile"