grep -c 出力に mtime を追加し、mtime で出力をソートします。

grep -c 出力に mtime を追加し、mtime で出力をソートします。

次の名前のログでいっぱいのディレクトリがあります。

info.log00001
info.log00002
info.log00003
...
info.log09999
info.log


私の現在の出力(grep -cを使用)

特定のエラーがどれだけ頻繁に発生するかを分析する必要があるため、そのディレクトリに移動して次のようにしてgrep -crw . -e "FooException BarError" | sort -n | less次のようにします。

./info.log00001: 1
./info.log00002: 0
./info.log00003: 42
...
./info.log09999: 25
./info.log: 0

ls -ltその後、修正日を確認して、最もエラーが発生した時期を分析できます。


私が望む出力(数と日付を含む)

とにかく、同じ行に数と日付を出力する方法を見つけたいと思います。これにより、私の分析が簡単になります。私は次のようなものが欲しい:

2015-09-31 10:00 ./info.log00001: 1
2015-09-31 10:15 ./info.log00002: 0
2015-09-31 10:30 ./info.log00003: 42
...
2016-04-01 13:20 ./info.log09999: 25
2015-09-31 13:27 ./info.log: 0


追加情報

理想的には、単一のコマンドでこれを実行したいのですが、最初にgrepコマンドの出力をファイルに入れてからそのファイルを処理することも可能です。

また、日付形式または日付が行の終わりであるか行の始まりであるかについてはあまり気にしません。私が望むのは、ファイルを最も古いものから始めて日付で並べ替えることです(名前の中で最小の数字を持つファイルでもあります)。

達成できる方法を見つけました。似たようなものawkgrepしかし、私の場合は、出力からファイル名を解析するので動作しません。私の場合、grep出力にはファイルパスよりも多くのテキストが含まれています。

これについてのフィードバックをいただきありがとうございます。

答え1

gnu findファイル名に改行文字が含まれていないと仮定すると、 'findを使用できます。-printf希望の形式でmtime+ファイル名を出力して実行し、grep数を取得します。

find . -type f -printf '%TY-%Tm-%Td %TH:%TM %p: ' -exec grep -cw "whatever" {} \; | sort -k1,1 -k2,2

または、zsh変更時間に基づいてグローバルに並べ替えることができます(次のように)。グローバル予選.- 一般ファイルの選択、Om降順のソート時間) 次に、各ファイルに対してmtime印刷を使用します。statモジュール、ファイル名を入力し、次のように数を取得しますgrep

zmodload zsh/stat
for f in ./**/*(.Om)
do
printf '%s %s\t%s %s: ' $(zstat -F '%Y-%b-%d %H:%M' +mtime -- $f) $f
grep -cw "whatever"  $f
done

答え2

バッシュ構成

shopt -s globstar
join -o 1.2,0,2.2 -t$'\034' <(stat -c $'%n\034%y' ** | sort) \
                            <(grep -crw "..." | sort | sed -r $'s/:([^:]*)/\034\\1/') \
                             | tr '\034' '\t'

そこには何か面白いものがありますが\034、それは文字の8進値ですFS。これはそれは想像できる既存のファイル名にこの文字が含まれている場合は、必要に応じて区切り文字を変更できます。

このstatコマンドは,各ファイルのファイル名と修正時間を繰り返し出力します。

grepコマンドに精通しています。最後のコロンをFS文字に翻訳しました。

FS文字を取得するには、bashのANSI-C引用文をstatとsedで使用する必要があります。

このjoinコマンドは、stat 出力を grep 出力に関連付け、「date FS filename FS count」を出力します。

その後、FSを[全般]タブに変換しました。

答え3

Perlベースのソリューション:

perl -lne 'if ($.==1) {
 print localtime($t)." $f: $c\n" if defined $t; 
 $c=0; $f=$ARGV; $t=(stat($f))[7];} $c++ if /$expr/o; 
} BEGIN { $expr=shift @ARGV; push @ARGV,"/etc/hosts"; 
' "search-expression" info.log

注:テストされていません。

ここにいくつかの標準的なPerlのヒントがあります。コードを-n囲みます。 1のwhile (<>) {場合は$.新しいファイルです。ファイルを処理する場合は、タイムスタンプ、ファイル名、数などの要約情報を印刷します。これで、最初の行に対してのみ現在のファイル名、ファイルのmtimeタイムスタンプを取得し、カウンタをリセットします。各行に必要な正規表現と一致する場合は、カウンタを増やします。 while ループを終了し、実行されるいくつかの開始コードを開始します。今後前のブロック。最初の引数を正規表現として使用し、各行で一致させます。これで、パラメータリストから最初のパラメータを削除します。次に、追加最終式をトリガーするダミーファイルが引数リストに追加されますprint。これは無害なハッキングです。

関連情報