何をしているのか

何をしているのか

入力ファイル

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

sedStream 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

関連情報