awk '/10:..:/, /13:..:/' server.log > /tmp/awktmp
誰かが私に与えた命令を試してみました。午前10時から午後13時の間にログを見つけるのは効果的ですが、完全には理解していません。
エレガントな解決策があれば教えてください。リモートサーバーは小型で高度なユーティリティがないことに注意してください。
ここで私が理解していないことは'/10:..:/, /13:..:/'
- 私は
10:..
それが2桁の数字を意味し10
、:
正確に一致することを理解しています。 - しかし、もう一つはどういう
:
意味ですか?
JavaScriptの正規表現のように、スラッシュが正規表現を入力するために使用されるようです。私はこれについて100%確信していません。
アップデート1:
時間は2番目の列にあり、フォーマットは次のとおりです。HH:MM:SS
アップデート2:
sed -n -e '/8:..:../,/9:..:../p' application.log > /tmp/sedtmp
私はこれを試しましたが、これも07:57:47
。
アップデート3
ログのすべての行に常にタイムスタンプが含まれるわけではありません。一部の行にはタイムスタンプがまったく含まれていません。この問題をどのように克服しましたか?私は愚かなawkを使用し、時間の価値がないすべての行を見逃しました。この問題を回避する方法はありますか?
私の言葉はそんな意味でした。
2023-08-07 09:20:35 0123456789 INFO CustomerLogoutResource:95 - Entering logout api.
2023-08-07 09:20:35 0123456789 ERROR AppExceptionMapper:87 - Exception has been thrown by container
2023-08-07 09:20:35 0123456789 ERROR AppExceptionMapper:555 - Unchecked Exception
java.lang.NullPointerException
at NullPointerExceptionExample.printLength(NullPointerExceptionExample.java:3)
at NullPointerExceptionExample.main(NullPointerExceptionExample.java:8)
答え1
10:00から11:00の間にログインがない場合、このメソッドはtoの行が見つから11:00
ず、13:00から14:00の間にログインがない場合、それ以降のすべての行が報告されます。少なくとも10〜11の間に1)。13:00
14:00
このような場合は、時間と範囲を語彙的に比較することをお勧めします。
たとえば、時間が3番目のフィールドにある場合:
awk '$3 >= "10:00:00" && $3 < "13:00:00"'
キュー内の時間がどこにあるかわからない場合は、次のことができます。
perl -lne 'print if /\b\d\d:\d\d:\d\d\b/ &&
$& ge "10:00:00" &&
$& lt "13:00:00"'
または:
LC_ALL=C awk 'match($0, /[0-2][0-9]:[0-5][0-9]:[0-5][0-9]/) && \
(t = substr($0, RSTART, 8)) >= "10:00:00" && \
t < "13:00:00"'
その範囲内のタイムスタンプを含むレポート行。タイムスタンプが指定された行の間にタイムスタンプが指定されていない行があり、それを報告したい場合は、beginning-condition, end-condition {action}
質問の方法を使用できますが、正規表現の一致ではなく比較を使用するか、手動状態遷移を実行して上限を除外することもできます。
LC_ALL=C awk -v beg=10:00:00 -v end=13:00:00 '
match($0, /[0-2][0-9]:[0-5][0-9]:[0-5][0-9]/) {
t = substr($0, RSTART, 8)
if (t >= end) selected = 0
else if (t >= beg) selected = 1
}
selected'
答え2
このパターンは、/10:..:/
10 の数字、2 つの区切り記号、および:
その間の 2 つの文字と一致します。したがって、(入力行内のどこにでも)時間と一致します。例: 10:35:22
。ただし、含まれている行と一致するため、This10:ZZ:Camels
あまり良いテストではありません。
より良いパターンは、分と秒が00から/10:[0-5][0-9]:[0-5][0-9]/
59の範囲にあることを確認することです。ただし、時間が特定のフィールドにあるか、その時間に空白があるか、またはレコードの先頭の近くに空白があるかどうかを確認することも役立ちます。何が必要かをよりよく理解するために、いくつかのサンプル入力行を投稿できますか?
2つのパターンをコンマで区切ると、最初のパターンが検出された場合は一致が「オン」になり、2番目のパターンが検出されると一致は「オフ」になります。日付がまったく含まれていなくても、そのイベント間のすべての行に一致します。
/1[0-2]:[0-5][0-9]:[0-5][0-9]/
これは、順序に関係なく、10:00:00から12:59:59の間の個々の行だけを一致させる単一のパターンとはかなり異なります。
答え3
awkモード:
/regA/,/regB/
regA に一致する最初の行から regB に一致する最初の行まで True です。通常のように、何かが式と一致する場合:一致するときに実行するアクションを正確に指定する式の後に何もない場合、デフォルトの動作は式が真の行を{ actions }
印刷することです。
今、彼らは以下を選択します:
/10:..:/, /13:..:/
hh:10:ssではなく10:mm:ssと一致することを確認してください。 (それらは時間参照がhh:mm:ssで、時間の前に「:」がないと仮定してこれを行います...これは、使用された日付形式によっては必ずしも正確ではありません。コメントで述べたように、一致する可能性があります。ものもあります。
行の先頭が常に次のようになることがわかっている場合:
YYYY-MM-DDThh:mm:ss+hh:mm
# For exemple:
# 2023-07-17T11:14:02+02:00 , which is following internationnal recommendations
# of displaying date and time (and timezone)
次のように、より密接に一致させることができます。
/^2023-07-17T10:/,/^2023-07-17T13:/
そして、行の先頭(^)でのみ一致することを確認し、表示される行のどの部分でも一致しないようにしてください。
答え4
ログファイルの2つのタイムスタンプの間でログを選択するための考えられる解決策は次のとおりです。このスクリプトは、ログファイルにスペースで区切られた列があり、2番目の列に形式のタイムスタンプが含まれていると仮定しますHH:MM:SS
。おそらく最もエレガントではありませんが、少なくとも明らかです。
awk -F" " '$2 >= "09:00:00" && $2 <= "12:00:00"' server.log
-F" "
フィールド区切り文字を空白文字に設定します。$2
入力ファイルの各行にある2番目のフィールドを表します(この場合、フィールドはスペースで区切られます)。>= "09:00:00"
2番目のフィールドの値が「09:00:00」以上であることを確認してください。&&
条件を結合する論理演算子です。 「そして」という意味$2 <= "12:00:00"
2番目のフィールドの値が「12:00:00」以下であることを確認してください。sever.log
入力ファイルです
ソリューション検証
server.log
次の内容は次のとおりです。
2023-07-18 08:55:32 - Log entry 1
2023-07-18 09:10:15 - Log entry 2
2023-07-18 10:30:47 - Log entry 3
2023-07-18 11:45:02 - Log entry 4
2023-07-18 12:05:21 - Log entry 5
2023-07-18 13:20:33 - Log entry 6
出力:
[get@me test]$ awk -F" " '$2 >= "09:00:00" && $2 <= "12:00:00"' server.log
2023-07-18 09:10:15 - Log entry 2
2023-07-18 10:30:47 - Log entry 3
2023-07-18 11:45:02 - Log entry 4