入力ファイル
Mar 19 06:10:16 ip-172-2-0-53 sendmail[28131]: v2JDA1k4028131: to=root, ctladdr=root (0/0), delay=00:00:15, xdelay=00:00:00, mailer=relay, pri=30580, relay=[127.0.0.1] [127.0.0.1], dsn=2.0.0, stat=Sent (v2JDAG5W028134 Message accepted for delivery)
Mar 19 14:41:26 ip-172-2-0-53 sendmail[29483]: v2JLfNFN029481: to=<[email protected]>,<[email protected]>, delay=00:00:03, xdelay=00:00:03, mailer=esmtp, pri=151738, relay=ifaded-com.mail.p...ction.outlook.com. [xx.xxx.x.x], dsn=2.0.0, stat=Sent (<[email protected]> [InternalId=31288836753166, Hostname=ERGsDGddssdD5.namprd07.prod.outlook.com] 8924 bytes in 0.309, 28.142 KB/sec Queued mail for delivery)
Mar 19 06:10:26 ip-172-2-0-53 sendmail[28131]: v2JDA1k4028131: to=root, ctladdr=root (0/0), delay=00:20:15, xdelay=00:00:00, mailer=relay, pri=30580, relay=[127.0.0.1] [127.0.0.1], dsn=2.0.0, stat=Sent (v2JDAG5W028134 Message accepted for delivery)
私は次のコマンドを試しました
cat logh.txt | grep -E -o " delay=.[^,]*|^[^ip]+"
日付より前の5つの遅延時間を知りたいです。 llinuxコマンドを使用してこの問題を解決するにはどうすればよいですか?私は次のような結果を得ます。
Mar 19 06:10:16
delay=00:00:15
Mar 19 14:41:26
delay=00:00:03
Mar 19 06:10:26
delay=00:20:15
希望の出力
Mar 19 06:10:26 delay=00:20:15
Mar 19 06:10:16 delay=00:00:15
Mar 19 14:41:26 delay=00:00:03
答え1
複数のパスが必要です。sed
、、、sort
を使用するソリューションは、head
希望のcut
順序で上位5つを提供します。
sed -e 's/^\([A-Za-z]\{3\} \{1,2\}[0-9]\{1,2\} \{1,2\}\([0-9]\{2\}:\)\{2\}[0-9]\{2\}\).* \(delay=\([0-9]\{2\}\):\([0-9]\{2\}\):\([0-9]\{2\}\)\).*/\4\5\6 \1 \3/' | sort -nr | head -n5 | cut -d\ -f2-
入力した入力に応じて、以下が放出されます。
Mar 19 06:10:26 delay=00:20:15
Mar 19 06:10:16 delay=00:00:15
Mar 19 14:41:26 delay=00:00:03
(入力が提供したログ形式であり、目的のデータを含む行のみを提供するとします。最初に追加のgrepを追加する必要があるかもしれません。)
それは何してるの?
それを分析しましょう。
sed
sed
フローエディタを表します。通常、テキストストリームに正規表現を適用するために使用されます。
sed正規表現
's/^\([A-Za-z]\{3\} \{1,2\}[0-9]\{1,2\} \{1,2\}\([0-9]\{2\}:\)\{2\}[0-9]\{2\}\).* \(delay=\([0-9]\{2\}\):\([0-9]\{2\}\):\([0-9]\{2\}\)\).*/\4\5\6 \1 \3/'
かなりの内容ですが、避けるべき内容です。悲惨な逆追跡。
私たちは正規表現の置換を使用しています。このアプリが何をしているかについて詳しくは、正規表現101を試してください。今、入力が必要であることを知っています。
Mar 19 06:10:16 ip-172-2-0-53 sendmail[28131]: v2JDA1k4028131: to=root, ctladdr=root (0/0), delay=00:00:15, xdelay=00:00:00, mailer=relay, pri=30580, relay=[127.0.0.1] [127.0.0.1], dsn=2.0.0, stat=Sent (v2JDAG5W028134 Message accepted for delivery)
Mar 19 14:41:26 ip-172-2-0-53 sendmail[29483]: v2JLfNFN029481: to=<[email protected]>,<[email protected]>, delay=00:00:03, xdelay=00:00:03, mailer=esmtp, pri=151738, relay=ifaded-com.mail.p...ction.outlook.com. [xx.xxx.x.x], dsn=2.0.0, stat=Sent (<[email protected]> [InternalId=31288836753166, Hostname=FOOBAR1.namprd07.prod.outlook.com] 8924 bytes in 0.309, 28.142 KB/sec Queued mail for delivery)
Mar 19 06:10:26 ip-172-2-0-53 sendmail[28131]: v2JDA1k4028131: to=root, ctladdr=root (0/0), delay=00:20:15, xdelay=00:00:00, mailer=relay, pri=30580, relay=[127.0.0.1] [127.0.0.1], dsn=2.0.0, stat=Sent (v2JDAG5W028134 Message accepted for delivery)
そしてそれに変換
000015 Mar 19 06:10:16 delay=00:00:15
000003 Mar 19 14:41:26 delay=00:00:03
002015 Mar 19 06:10:26 delay=00:20:15
sed 正規表現の一致
^\([A-Za-z]\{3\} \{1,2\}[0-9]\{1,2\} \{1,2\}\([0-9]\{2\}:\)\{2\}[0-9]\{2\}\).* \(delay=\([0-9]\{2\}\):\([0-9]\{2\}\):\([0-9]\{2\}\)\).*
まず、日付コンポーネントを明示的に一致させます。後で出力する必要があります。次に、出力したい遅延とそのタイミングコンポーネントを個別に見つけて一致させます。後でアライメントにはタイミングコンポーネントが必要です。
sedの正規表現の置換
\4\5\6 \1 \3
正規表現の代替の観点から、私たちはもともと持っていた":"区切り文字を使用せずにキャプチャしたタイミングコンポーネントを取得して接続します。後で使用するので、これは重要ですsort
。タイミングコンポーネントの後に日付文字列と完全な元の遅延文字列を追加します。
タイプ
sort -nr
これで、入力は文字列タイムスタンプではなく10進数で始まるため、sort
数値パターンを使用して-n
フラグを付けることができます。
デフォルトでは、ソートsort
は昇順で行われ、最も大きい値が最後に続きます。処理するという意味なのでみんなの出力はsort
最大のN値を探します。ソート-r
フラグを使用して出力の順序を変更し、最大の値を最初に出力し、head
「テール」を置き換えることができます。
この時点で私たちの出力は次のとおりです。
002015 Mar 19 06:10:26 delay=00:20:15
000015 Mar 19 06:10:16 delay=00:00:15
000003 Mar 19 14:41:26 delay=00:00:03
頭
head -n5
この時点で、入力は最初に最大値を持ち、最大5つの値が必要であることをすでに知っています。したがって、head
sパラメータを使用して必要な値の数を-n
指定します。head
この場合、実際には5つ以上の値がないため、入力に対するすべての出力を取得します。
002015 Mar 19 06:10:26 delay=00:20:15
000015 Mar 19 06:10:16 delay=00:00:15
000003 Mar 19 14:41:26 delay=00:00:03
切る
cut -d\ -f2-
sed
不要になるため、最初のステップで挿入した数値ソートキーを削除する必要があります。これを行うために、提供されたcut
各行で目的のフィールドを選択できるようにします。
-d
フィールド区切り記号、区切り文字が何であるかを示すためにcutパラメータを使用します。フィールド区切り文字は空白なので、\
エスケープする必要があります-d\
。
cut
の観点から見ると、これは行を分割002015 Mar 19 06:10:26 delay=00:20:15
します002015
Mar
19
06:10:26
delay=00:20:15
。
必要なフィールドを指定するには、を使用します-f
。最初のフィールドを除くすべてのフィールドが必要なので、を使用して目的の-f2-
出力を提供します。
Mar 19 06:10:26 delay=00:20:15
Mar 19 06:10:16 delay=00:00:15
Mar 19 14:41:26 delay=00:00:03
答え2
perl -lane '
print join $", /\sdelay=\K(\S+)(?=,)/, splice(@F, 0, 3), /\s\K(delay=\S+)(?=,)/;
' | sort -t: -k 1,1nr -k 2,2nr -k 3,3nr | cut -d\ -f2- | head -n 5