입력 파일
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개의 값이 필요하다는 것을 이미 알고 있습니다. 그래서 우리는 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