它在做什麼

它在做什麼

輸入檔

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

您將需要多次通行證。這是一個使用sedsortheadcut按您想要的順序給出前 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

由於我們的輸入現在以十進制數字而不是字串時間戳開頭,因此我們可以使用sort的數字模式,並用-n標誌指定。

預設情況下,sort按升序排序,將最大值放在最後。因為這意味著處理全部ofsort的輸出找到最大的 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 個值。所以我們使用heads-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:15002015 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

相關內容