ログを解析するために設計したPerlコマンドを使用したいと思います。これまで私が達成しようとしているのは、特定のタイムスタンプ形式を抽出してホストを検索することです。ログは次のとおりです
2016-05-07T09:07:04.933343+00:00 heroku[router]: status=301 bytes=680 service=2698ms connect=1ms dyno=web.2 fwd="10.29.10.29" at=info host="jamaican.com" request_id=32fc8d88-99f8-4cc2-89f9-284d059eebf8 method=GET path="/blog"
私のコマンドは目的の日付形式を解析できますが、出力にホストを追加する方法がわからないようです。どんな提案でもいいでしょう!
cat test.log |
perl -lne 'print $1 if /^([0-9]+[-]+[0-9]+[0-9]+[-]+[0-9]+[0-9]+[T]+[0-9]+[0-9]+[:]+[0-9]+[0-9]+[:]+[0-9]+[0-9])/'
答え1
この試み:
perl -nle'($time, $host) = /^(\S+)\s(?:\S+\s+){8}\S+="(\S+?)"/; print "$time $host"'
出力:
2016-05-07T09:07:04.933343+00:00 jamaican.com
\S
非空間を表す\s
スペースです(?:)
キャッチされていない論理的なグループ化です。{8}
スキップした「単語」です。\S+="(\S+?)"
=
意味:2つの引用符の間にある内容までスキップしてキャプチャします。"
($time, $host) = /.../
キャプチャされた2つのグループ$time
と$host
答え2
ホスト名をキャプチャするには、2番目のキャプチャグループを使用する必要があります。
たとえば、サンプル入力を使用すると、次のようになります。
$ cat test.log
2016-05-07T09:07:04.933343+00:00 heroku[router]: status=301 bytes=680 service=2698ms connect=1ms dyno=web.2 fwd="10.29.10.29" at=info host="jamaican.com" request_id=32fc8d88-99f8-4cc2-89f9-284d059eebf8 method=GET path="/blog"
このperl one-linerはタイムスタンプとホスト名フィールドを抽出します。また、\d
各数値に一致回数がある数値の正規表現を一部改善しました。
$ perl -lne 'print "$1 $2" if (m/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d+\+\d{2}:\d{2}) ([^ ]+) /)' test.log
2016-05-07T09:07:04.933343+00:00 heroku[router]:
別のオプション:
$ perl -lne 'print "$1 $2 $3" if (m/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d+\+\d{2}:\d{2}) ([^[]+)\[([^]]+)\]/)' test.log
2016-05-07T09:07:04.933343+00:00 heroku router
host="jamaican.com"
私はあなたのローカルコンピュータのホスト名が欲しいと仮定します。 (私はログエントリの部分にも気づいていませんでした)。これは望ましくない可能性があるため、ホスト名の後に二重引用符を使用するには、host=
次の手順を実行します。
$ perl -lne 'print "$1 $2" if (m/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d+\+\d{2}:\d{2}).*host="([^"]+)"/)' test.log
2016-05-07T09:07:04.933343+00:00 jamaican.com
または(より簡単に):
$ perl -lne 'print "$1 $2" if (m/(^\S+).*host="([^"]+)"/)' test.log
2016-05-07T09:07:04.933343+00:00 jamaican.com
またはタイムスタンプを抽出し、.をDate::Parse
使用して解析してからDate::Format
。
$ perl -MDate::Parse -MDate::Format -lne \
'if (m/(^\S+).*host="([^"]+)"/) {
print join(" ", time2str("%Y-%m-%d %R %z",str2time($1)), $2)
}' test.log
2016-05-07 19:07 +1000 jamaican.com
注:タイムスタンプは現地時間帯に変換されます(私の場合は+1000またはオーストラリア東部標準時)。 time2str()
デフォルトではローカルタイムゾーンが使用されますが、3番目の引数(time2str(TEMPLATE, TIME [, ZONE])
)を指定して別のタイムゾーンの時間を出力することができます。
$ perl -MDate::Parse -MDate::Format -lne 'if (m/(^\S+).*host="([^"]+)"/) {
print join(" ", time2str("%Y-%m-%d %R %z",str2time($1),"+0"), $2)
}' test.log
2016-05-07 09:07 +0000 jamaican.com