先週のシステムログを分析するスクリプトを作成したいと思います。
しかし、私のsyslogは「5月22日」のような愚かな日付形式で記録されます。 2013-05-22として記録されている場合、これは簡単です。
awk / bash / perl / sedを使用して2つの日付/時刻の間のすべての行ログを簡単に「grep」する方法はありますか?
答え1
これは私にとってはあまりにも複雑ですが、あなたにとっては面白いかもしれません。
perl -p -e '
BEGIN{
@months=qw(jan feb mar apr may jun jul aug sep oct nov dec);
$month_number{$_}=++$i for @months;
$months_regex= join "|",@months;
}
s/^\s*($months_regex)[a-z]*\s+/$month_number{lc $1}-/i'
/var/log/syslog
これにより、簡単に解析できるように見えるMM-DD形式(ゼロパディングなしの月番号)の日付を含むログ行が標準出力として印刷されます。大文字と小文字に関係なく、完全な形式で提供された月名と3文字形式で提供された月名を処理します。
編集する
月番号をゼロで埋めるには、次のよう++$i
に置き換えます。sprintf "%02d",++$i
編集2 2つのエラーを修正しました。ありがとうございます。l0b0さんのコメントは次のとおりです。
- 月のリストに「5月」を追加してください。
- ゼロパディングレシピを次に変更します。
sprintf "%02d", ++$i
答え2
これが私がPerlでやる方法です。たとえ私は他の答えを好みますが!
use DateTime::Format::Strptime;
my $parser = DateTime::Format::Strptime->new( pattern => '%B %d %Y');
m/^(\w+ \d+)/;
print $parser->parse_datetime("$1 " . DateTime->now->year)->ymd;
答え3
大丈夫ですか?
各行の保持日は> 10日と< 18日です。
awk '$2 > 10 && $2 < 18 {print}' file
月名を含む:
awk '$1 == "May" && $2 > 10 && $2 < 18 {print}' file
4月27日から5月4日までの期間:
awk '($1 == "Apr" && $2 > 26) || ($1 == "May" && $2 < 5){print}' file
修正する:
getlineを使用したおおよその変形:
awk '"date '+%m%d' -d " $1$2 | getline date; close("date"); \
date > 426 && date < 505 {print}' file
スクリプトの使用:
awk -v from=520 -v to=523 '
{
d = ((match("JanFebMarAprMayJunJulAugSepOctNovDec", $1) + 2) / 3 )$2;
if (d >= from && d <= to)
print;
}
' file
スイッチを使用してください:
awk -v from=520 -v to=523 '
function date2time()
{
switch ($1) {
case "Jan": return 1$2; break;
case "Feb": return 2$2; break;
case "Mar": return 3$2; break;
case "Apr": return 4$2; break;
case "May": return 5$2; break;
case "Jun": return 6$2; break;
case "Jul": return 7$2; break;
case "Aug": return 8$2; break;
case "Sep": return 9$2; break;
case "Oct": return 10$2; break;
case "Nov": return 11$2; break;
case "Dec": return 12$2; break;
}
}
{
d = date2time();
if (d >= from && d <= to)
print;
}
' file
配列を使用して下さい:
... oh see you have gotten your answer ;)