入力ファイル
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
複数回のパスが必要になります。、、を使用して、上位 5 つを希望の順序で表示するソリューションをsed
次にsort
示しhead
ますcut
。
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
Stream Editor の略です。テキスト ストリームに正規表現を適用するために日常的に使用されます。
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/'
かなり長い言葉ですが、避けるためにはそうする必要があるのです破滅的な後退。
正規表現の置換を使用しています。詳細を確認するには、Regex101を試す今のところ、次の入力を受け取ることを知っておいてください。
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 個の値を見つけるには、sort の-r
フラグを使用して出力順序を逆にします。これで、最大値が最初に出力され、head
`tail.
この時点での出力は次のようになります。
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
の-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
。これにより、提供された各行から必要なフィールドを選択できます。
cut の-d
パラメータを使用して、フィールド セパレータ、つまり区切り文字を指定します。フィールド セパレータは空白文字なので、 でエスケープして にする必要があり\
ます-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