그게 뭐하는 거야?

그게 뭐하는 거야?

입력 파일

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

이제 입력이 문자열 타임스탬프가 아닌 십진수로 시작하므로 sort숫자 패턴을 사용하고 -n이를 플래그로 지정할 수 있습니다.

기본적으로 sort정렬은 오름차순으로 이루어지며 가장 큰 값이 맨 나중에 옵니다. 처리한다는 의미이기 때문에모두의 출력은 sort가장 큰 N 값을 찾습니다. 이제 정렬 -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제공된 각 행에서 원하는 필드를 선택할 수 있도록 합니다.

-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

관련 정보