
この質問をstackoverflowに移動する必要がありますか?
Javaアプリケーションによって生成されたログファイルを読み取るには、log4jを使用する必要があることがよくあります。通常、記録されたメッセージ(ログエントリと呼ばれる)は複数行にまたがっています。例:
INFO 10:57:01.123 [Thread-1] [Logger1] This is a multi-line
text, two lines
DEBUG 10:57:01.234 [Thread-1] [Logger2] This entry takes 3 lines
line 2
line 3
各ログエントリは新しい行から始まり、行の最初の単語はTRACE、DEBUG、INFO、またはERRORと少なくとも1つのスペースです。これには2つのログエントリがあります。 1つ目はミリ秒123、もう1つはミリ秒234です。
ログエントリをフィルタリングする(grepは行のみをフィルタリングする)クイックコマンド(sed / grep / awk / etcの組み合わせを使用)が必要です。たとえば、「Logger2」というテキストを含むすべてのログエントリを削除します。
私は次の変換を考えました。
1)同じログエントリに属する行を連結するには、特殊文字シーケンスを使用します(例:##)。すべてのログエントリは正確に1行を占めます。
INFO 10:57:01.123 [Thread-1] [Logger1] This is a multi-line##text, two lines
DEBUG 10:57:01.234 [Thread-1] [Logger2] This entry takes 3 lines##line 2##line 3
2)grep
3)行を再分割します(例:##を\ nに置き換えます)。
ステップ1で問題が発生しました。 sedの経験が足りません。
上記のステップ3は必要ないかもしれませんし、sedはすべてのことをするかもしれません。
答え1
複数の楽器を混ぜる必要はありません。課題はsed
通過のみ可能
sed '/^INFO\|^DEBUG\|^TRACE\|^ERROR/{
/Logger2/{
:1
N
/\nINFO\|\nDEBUG\|\nTRACE\|\nERROR/!s/\n//
$!t1
D }
}' log.entry
答え2
Perlマルチラインロギングフィルタ(ロギング開始タグ)
次のPerlスクリプトを作業プロトタイプとして使用します。
使用script_path regular_expression log_files
例script_path "line \d" log_file_1 log_file_2
#!/usr/bin/perl
$pattern = qr/(?^s)$ARGV[0]/; shift; # process filtering expression
# (?^s) - treats matched string as single line
my $line = ''; # accumulates current log file record/paragraph
while(<>) {
if( /^(TRACE|DEBUG|INFO|ERROR) /o ) { # start of new record
&flush; # flush/print previous recors
}
$line.=$_;
}
&flush;
exit;
sub flush {
local $_ = $line;
if( length($_) and /$pattern/ ) {
print;
}
$line = '';
}
答え3
答えに基づいてhttps://stackoverflow.com/questions/9605232/merge-two-lines-into-oneこれはぴったりです。
#!/usr/local/bin/bash
PATTERN1='TRACE *';
PATTERN2='DEBUG *';
PATTERN3='INFO *';
PATTERN4='ERROR *';
LINEOUT=""
while read line; do
case $line in
$PATTERN1)
echo $LINEOUT
LINEOUT="$line"
;;
$PATTERN2)
echo $LINEOUT
LINEOUT="$line"
;;
$PATTERN3)
echo $LINEOUT
LINEOUT="$line"
;;
$PATTERN4)
echo $LINEOUT
LINEOUT="$line"
;;
"")
LINEOUT=""
;;
*) LINEOUT="$LINEOUT ## $line"
;;
esac
done
echo $LINEOUT
注:これにより、出力の先頭にスペースが追加されます。