システムログに追加されたファイル固有のエントリ

システムログに追加されたファイル固有のエントリ

いつものように、syslog次のようにアイテムの内容を確認できます。

cat /var/log/syslog | grep myentry

myentry特定のファイルにすべての行を追加する必要があります。もちろん、上記のコマンドの出力をファイルにリダイレクトするだけでは機能しません。なぜなら、最後に追加してもすべての行を追加するからです。

syslog私の心に浮かんだ最初の解決策は、ターゲットファイルの最後の行が見つかるまですべての行を繰り返すことでした。その後、以下にすべての内容を追加できます。このタスクを定期的に実行する(つまり、cronjobを使用するか、bashでより単純にタイムアウトループを使用して)、トリックを実行する必要があります。

同じことを行うよりスマートでエレガントな方法はありますか?

編集する

terdonのリクエストを追加しました。

私のシステムログの例:

Jan 17 13:03:18 stm32mp1-abc local2.info chat[15782]: CONNECT
Jan 17 13:03:18 stm32mp1-abc local2.info chat[15782]:  -- got it
Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Ready
Jan 17 13:03:18 stm32mp1-abc local2.info chat[15782]: send (^M)
Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Init complete
Jan 17 13:03:18 stm32mp1-abc daemon.info pppd[14362]: Serial connection established.
Jan 17 13:03:18 stm32mp1-abc daemon.info pppd[14362]: Using interface ppp0

追加する既存のファイルの例:

Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Ready

これら2つのファイルの最終出力は次のとおりです。

Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Ready
Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Init complete

修正する

わかりました、私に必要なようです。非常に私の説明に関係なく、特に例を見てみましょう。新しい例:

システムログ

Jan 17 13:03:18 stm32mp1-abc local2.info chat[15782]: CONNECT
Jan 17 13:03:18 stm32mp1-abc local2.info chat[15782]:  -- got it
Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Ready
Jan 17 13:03:18 stm32mp1-abc local2.info chat[15782]: send (^M)
Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Init complete
Jan 17 13:03:18 stm32mp1-abc daemon.info pppd[14362]: Serial connection established.
Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Start operations
Jan 17 13:03:18 stm32mp1-abc daemon.info pppd[14362]: Using interface ppp0

電流出力

Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Init complete

新しい出力

Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Init complete
Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Start operations

明確でなければなりません。

  1. outputファイルが空の場合は、すべての行をsyslog/myentries追加します。
  2. outputファイルが空でない場合はすべて追加 syslog/myentries行(一致する行から)
  3. outputファイルが空でなく一致するものがない場合でも、すべて追加します。 syslog/myentries行(最後のタイムスタンプ以降)

前述のように、無差別代入を使用してこれを実行できます。すべての行を繰り返し、条件を確認し、必要に応じて追加します。

アイテムを自動的に分割する提案など、より簡単な解決策を探していましたが、syslog方法が見つかりませんでした。

答え1

既存のターゲットファイルの最後の行を保存します。次に、次のコマンドを使用してシステムログawkファイルを逆方向​​に解析しますtac

p=$(tail -n1 output)
tac syslog | awk -v p="$p" '$0 == p{exit} /myentry/' | tac >> output

最後の行が見つかると(戻る)awk終了します。見つからない場合、または出力が最初に空の場合は、ファイル全体を解析します(最初に空の出力に対してsyslogに空白行がないとします)。今回もこのように必要最小限の行数を検索するため、大容量ファイルに対しては良好な性能を発揮すると予想されます。


また、次の簡単で効果的なコマンドをツールボックスに保存します。

awk '!seen[$0]++' output > output.tmp && mv output.tmp output

順序を維持しながら、いつでもターゲットファイルを変更するために実行できます(何らかの理由で重複ファイルがそこに到達した場合)。

答え2

簡単な方法は次のとおりです。

$ awk 'NR==FNR{a[$0]++; next}/myentry/ &&  !a[$0]' myentries syslog 
Jan 17 13:03:18 stm32mp1-abc user.info myentry[14300]: Init complete

これにより、一致する新しい行が選択されるため、元のファイルにリダイレクトするだけです。

awk 'NR==FNR{a[$0]++; next}/myentry/ &&  !a[$0]' myentries syslog >> myentries

関連情報