テスト文字列に一致するログファイルの最後の行を取得し、別のログファイルに出力したいと思います。
さまざまなテキスト文字列をテストし、出力に応じてさまざまなログファイルに送信する必要があります。
私はこれを使用しています:
tail -f -n 1 input.log | grep string1 >>output1.log
その後、次のようにテストを繰り返したいと思います。
tail -f -n 1 input.log | grep string2 >>output2.log
tail -f -n 1 input.log | grep string3 >>output3.log
効率的な単一のbashスクリプトでこれをどのように達成できますか?
答え1
grepの代わりにawkを使用してください。
awk '/string1/ { print >> "output1.log" ; fflush() }
/string2/ { print >> "output2.log" ; fflush() }
/string3/ { print >> "output3.log" ; fflush() }' input.log
この出力みんな行を対応するoutput.logファイルと一致させます。それはあなたの矛盾tail -f
と要件を理解できないからですtail -n 1
。input.log
現在の最後の行から始めるには、tail -f -n 1
スクリプトをパイプしawk
てinput.log
その行の終わりを削除します。例えば
tail -f -n 1 input.log | awk '...same awk script as above...'
tee
また、grep
それを行うことができますし、プロセスの交換
(しかし、かなり遅くなるでしょう):
tee >(grep --line-buffered string1 >> output1.log) \
>(grep --line-buffered string2 >> output2.log) \
>(grep --line-buffered string3 >> output3.log) < input.log
または
tail -f -n 1 input.log | tee .....
メモ:fflush()
in -solutionawk
およびin-solution--line-buffered
オプションは、(または他の無限プロセス)の出力をまたはにパイプする場合にのみ必要です。tee
tail -f
awk
tee
これがなければ、出力ファイルは出力バッファ(awkまたはgrep)がいっぱいになったときにのみ書き込まれます。ジョブがバッファに書き込まれていない出力で中断された場合(たとえば、Ctrl-Cを押す)、すべての出力は依然として失われます。バッファ。
これを使用すると、両方のソリューションがはるかに遅くなります(書き込みごとに出力をフラッシュするため)。ただし、入力ファイルが非常に大きくない場合は問題になりません。
ちなみに、これは入力の終わりに問題ではありません。この場合、awk と grep はどちらも終了する前に出力バッファを自動的にフラッシュします。
別の選択肢は、サブシェルでパイプawk
(または)を実行してCtrl-Cの割り込み信号をキャプチャして無視することです。tee
例えば
tail -f input.log | (
trap '' INT
awk '/string1/ { print >> "output1.log" }
/string2/ { print >> "output2.log" }
/string3/ { print >> "output3.log" }'
)
tail -f
Ctrl-Cを押すと影響しますが(終了)、実行中のサブシェルはawk
それを無視します。 awk
出力バッファをフラッシュし、tail
入力が完了して終了すると終了します。
バラよりawkスクリプトからCtrl-Cをキャプチャする別の例/説明。
ログファイルに従わない場合は、tail
's-f
オプションを使用しないでください。
tail -n 1 | .....
3つの文字列のすべての最後の項目をその出力ファイルに印刷するGuyの回答を使用するか調べます。
答え2
生産ラインに集中できるように、CASのソリューションを編集してください。
テスト文字列に一致するログファイルの最後の行を取得し、別のログファイルに出力したいと思います。
awk '
# every time theres a match, save that line into a variable
/string1/ { str1 = $0 }
/string2/ { str2 = $0 }
/string3/ { str3 = $0 }
END {
# and only print to file after reading the whole log.
print str1 >> "output1.log"
print str2 >> "output2.log"
print str3 >> "output3.log"
}' input.log
答え3
入力ファイル
praveen
ajay
abhi
praveen
ajay
abhi
kiran
tomato
私たちの要件は、別のテキスト文字列を検索し、出力を別のテキストファイルに書き込むことです。
同じ目的を達成するために、forループとsedコマンドを使用しました。
praveen、ajay、abhiコンテンツ検索を試み、結果をcontentsearch.txtに保存しました。
スクリプト
for i in praveen ajay abhi; do sed -n "/$i/p" input.txt > $i.txt; done
以下は出力になります
praveen.txt will contains line where praveen is present
ajay.txt will contains line where ajay is present
abhi.txt will contains where abhi is present
================================================== ============================
テスト文字列に一致するログファイルの最後の行を検索して別のファイルに出力するには、次のコマンドを使用します。
sed -n '/Contentsearch/p' input.txt | tail -1 > output.txt