
ファイル名.logというファイルがあり、その中には次のような内容が書かれています。
(2014-11-18 14:09:21,766), , xxxxxx.local, EventSystem, DEBUG FtpsFile delay secs is 5 [pool-3-thread-7]
(2014-11-18 14:09:21,781), , xxxxxx.local, EventSystem, DEBUG FtpsFile disconnected from ftp server [pool-3-thread-7]
(2014-11-18 14:09:21,798), , xxxxxx.local, EventSystem, DEBUG FtpsFile FTP File Process@serverStatus on exit - 113 [pool-3-thread-7]
(2014-11-18 14:09:21,798), , xxxxxx.local, EventSystem, DEBUG FtpsFile FTP File Process@serverStatus on exit - 114 [pool-3-thread-7]
(2014-11-18 14:09:21,799), , xxxxxx.local, EventSystem, DEBUG JobQueue $_Runnable Finally of consume() :: [pool-3-thread-7]
最も頻繁に DEBUG メッセージを生成するクラスを見つけようとしています。
この例では、FTPSファイルそしてジョブキューメッセージを生成する 2 つのクラスです。
私はこれを持っています
cat filename.log | sed -n -e 's/^.*\(DEBUG \)/\1/p' | sort | uniq -c | sort -rn | head -10
これにより、クラス名が生成され、最も頻繁に使用されるクラスがトップ 10 として表示されます。
問題は、これではクラスの数が分からないことですFTPSファイル4 としてカウントされます。各 FtpsFile ログ ファイルは、異なる一意のエンティティとしてカウントされます。
上記のコマンドを変更して、基本的に DEBUG の後の最初の単語を取得し、残りを無視してカウントするようにするにはどうすればよいでしょうか?
理想的には、4つのFtpsFileと1つのJobQueueを取得する必要があります
答え1
GNUの場合
sed
:sed 's/.*DEBUG \(\w*\).*/\1/' | uniq -c 4 FtpsFile 1 JobQueue
と
grep
:grep -Po 'DEBUG \K\w+' | uniq -c 4 FtpsFile 1 JobQueue
と
awk
:awk '$6=="DEBUG"{print $7}' | uniq -c 4 FtpsFile 1 JobQueue
最後のものは pure で実行できますawk
が、類似性を保つために にパイプしましたuniq
。
答え2
簡単な修正 - そのフィールドを分離するために次のカット コマンドを追加しました。
[host:~]$ cat logfile | cut -d" " -f7 | sort | uniq -c | sort -rn | head -10
4 FtpsFile
1 JobQueue
KISS に熱心ですが、これは名前にスペースが含まれるクラスには適用されません。
答え3
興味のあるフィールドの前のフィールドを参照しないようにするには、sed の代わりに awk を使用し、表示したいセクションを切り取ります。
[hunter@apollo: ~]$ cat filename.log | awk -F, '{ print $6 }' | cut -c 1-15 | uniq -c | sort -rn | head -10
4 DEBUG FtpsFile
1 DEBUG JobQueue
(注: 2 回ソートしていましたが、これは不要なようです)
編集: クラスの長さがわからない場合は、(cut の代わりに) 追加の awk コマンドを追加できます。
[hunter@apollo: ~]$ cat filename.log | awk -F, '{ print $6 }' | awk '{ print $1, $2 }' | uniq -c | sort -rn | head -10
4 DEBUG FtpsFile
1 DEBUG JobQueue