로그 파일을 필터링하고 두 일치 항목 사이에 몇 줄을 인쇄하고 마지막 일치 항목만 인쇄하고 싶습니다.
샘플 파일 내용:
2023-03-08 11:12:44,306 - Code Deploy - INFO - Received signal
2023-03-08 11:12:44,306 - Code Deploy - INFO - Received message signal
2023-03-08 11:12:44,306 - Code Deploy - INFO - Branch is Testing
2023-03-08 11:12:44,307 - Code Deploy - INFO - Deployment started
2023-03-08 11:13:31,782 - Code Deploy - INFO - Old version2_0_5_12
2023-03-08 11:13:31,783 - Code Deploy - INFO - New version2_0_5_13
2023-03-08 11:13:32,553 - Code Deploy - INFO - Permission fixed
2023-03-08 11:13:32,554 - Code Deploy - INFO - Deployment finished
2023-03-08 11:13:34,900 - Code Deploy - ERROR - !!!!!!!!!! EXCEPTION !!!!!!!!!(535, b'5.7.8 Username and Password not accepted. Learn more at\n5.7.8 https://support.google.com/mail/?p=BadCredentials z16-20020a170903019000b0019a97a4324dsm9818181plg.5 - gsmtp')Traceback (most recent call last):
File "/root/code-dployment/server/deploy.py", line 94, in send_email
server.login(gmail_user, gmail_password)
File "/usr/lib/python3.5/smtplib.py", line 729, in login
raise last_exception
File "/usr/lib/python3.5/smtplib.py", line 720, in login
initial_response_ok=initial_response_ok)
File "/usr/lib/python3.5/smtplib.py", line 641, in auth
raise SMTPAuthenticationError(code, resp)
smtplib.SMTPAuthenticationError: (535, b'5.7.8 Username and Password not accepted. Learn more at\n5.7.8 https://support.google.com/mail/?p=BadCredentials z16-20020a170903019000b0019a97a4324dsm9818181plg.5 - gsmtp')
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received message signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Branch is Testing
2023-03-09 11:52:57,195 - Code Deploy - INFO - Deployment started
2023-03-09 11:53:58,246 - Code Deploy - INFO - Old version2_0_5_13
2023-03-09 11:53:58,246 - Code Deploy - INFO - New version2_0_5_14
2023-03-09 11:53:58,498 - Code Deploy - INFO - Permission fixed
2023-03-09 11:53:58,498 - Code Deploy - INFO - Deployment finished
2023-03-09 11:54:00,797 - Code Deploy - ERROR - !!!!!!!!!! EXCEPTION !!!!!!!!!(535, b'5.7.8 Username and Password not accepted. Learn more at\n5.7.8 https://support.google.com/mail/?p=BadCredentials k17-20020aa790d1000000b005907716bf8bsm11097506pfk.60 - gsmtp')Traceback (most recent call last):
File "/root/code-dployment/server/deploy.py", line 94, in send_email
server.login(gmail_user, gmail_password)
File "/usr/lib/python3.5/smtplib.py", line 729, in login
raise last_exception
File "/usr/lib/python3.5/smtplib.py", line 720, in login
initial_response_ok=initial_response_ok)
File "/usr/lib/python3.5/smtplib.py", line 641, in auth
raise SMTPAuthenticationError(code, resp)
smtplib.SMTPAuthenticationError: (535, b'5.7.8 Username and Password not accepted. Learn more at\n5.7.8 https://support.google.com/mail/?p=BadCredentials k17-20020aa790d1000000b005907716bf8bsm11097506pfk.60 - gsmtp')
두 스키마 사이의 콘텐츠를 가져와야 합니다.
Pattern1 = '신호 수신'
Pattern2 = '배포 완료'
예상되는 결과:
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received message signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Branch is Testing
2023-03-09 11:52:57,195 - Code Deploy - INFO - Deployment started
2023-03-09 11:53:58,246 - Code Deploy - INFO - Old version2_0_5_13
2023-03-09 11:53:58,246 - Code Deploy - INFO - New version2_0_5_14
2023-03-09 11:53:58,498 - Code Deploy - INFO - Permission fixed
2023-03-09 11:53:58,498 - Code Deploy - INFO - Deployment finished
bash 스크립트에서 AWK 명령을 사용하고 싶습니다. 다음 명령을 사용하여 두 모드 간에 콘텐츠를 필터링하는 솔루션을 찾았습니다.
# awk '/Received signal/,/Deployment finished/' /tmp/result.log
전체 일치하는 행의 모든 항목을 인쇄하지만 일치하는 패턴의 마지막 항목만 인쇄하도록 필터링해야 합니다.
위 명령의 출력은 다음과 같습니다.
2023-03-08 11:12:44,306 - Code Deploy - INFO - Received signal
2023-03-08 11:12:44,306 - Code Deploy - INFO - Received message signal
2023-03-08 11:12:44,306 - Code Deploy - INFO - Branch is Testing
2023-03-08 11:12:44,307 - Code Deploy - INFO - Deployment started
2023-03-08 11:13:31,782 - Code Deploy - INFO - Old version2_0_5_12
2023-03-08 11:13:31,783 - Code Deploy - INFO - New version2_0_5_13
2023-03-08 11:13:32,553 - Code Deploy - INFO - Permission fixed
2023-03-08 11:13:32,554 - Code Deploy - INFO - Deployment finished
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received message signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Branch is Testing
2023-03-09 11:52:57,195 - Code Deploy - INFO - Deployment started
2023-03-09 11:53:58,246 - Code Deploy - INFO - Old version2_0_5_13
2023-03-09 11:53:58,246 - Code Deploy - INFO - New version2_0_5_14
2023-03-09 11:53:58,498 - Code Deploy - INFO - Permission fixed
2023-03-09 11:53:58,498 - Code Deploy - INFO - Deployment finished
답변1
awk를 사용하고 다음 스크립트 중 하나와 매우 유사합니다.@terdon의 답변하지만 제 생각에는 awk의 condition { action }
기본 구조를 사용하는 것이 좀 더 관용적입니다.
$ awk '
/Received signal/ { f=1; rec="" }
f { rec = rec $0 ORS }
/Deployment finished/ { f=0 }
END { if (f=="0") printf "%s", rec }
' file
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received message signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Branch is Testing
2023-03-09 11:52:57,195 - Code Deploy - INFO - Deployment started
2023-03-09 11:53:58,246 - Code Deploy - INFO - Old version2_0_5_13
2023-03-09 11:53:58,246 - Code Deploy - INFO - New version2_0_5_14
2023-03-09 11:53:58,498 - Code Deploy - INFO - Permission fixed
2023-03-09 11:53:58,498 - Code Deploy - INFO - Deployment finished
이것과 @terdon의 답변 사이의 약간의 기능적 차이점은 다음과 같습니다.
RS='\r\n'
ORS를 RS와 다른 값으로 설정하기로 결정한 경우(예: 로 변환하려는 경우ORS='\n'
) 필요한 레코드 종결자가 생성되고 @terdon은 ORS를 사용하여 대부분의 출력 끝에서 RS 값을 재현합니다.- 입력 파일에 줄이 없으면 @terdon은 빈 줄을 인쇄
Received signal
하고 파일은 출력을 생성하지 않습니다. - 입력에 두 개의 구분 기호가 있는 경우 이 명령은 구분 기호 사이의 텍스트만 인쇄하는 반면, @terdon은 후속 줄이
Received signal
없더라도 줄 뒤의 모든 항목을 인쇄합니다Deployment finished
.
귀하의 질문 과 관련하여 awk '/Received signal/,/Deployment finished/' /tmp/result.log
- 범위 표현식을 사용하지 말고 플래그를 사용하십시오.awk에서 시작 끝 범위 표현이 항상 유용함. 범위 표현식을 사용하는 지금까지 게시된 모든 답변에서 볼 수 있듯이 동일한 조건에 대해 두 가지 테스트가 필요합니다.
답변2
파일을 반전시켜 범위에 없는 모든 줄을 제거 /Deployment finished/,/Received signal/
하고 줄 범위의 끝이 일치하는 즉시 종료합니다. 그런 다음 결과를 반전시킵니다.
tail -r file |
sed -e '/Deployment finished/,/Received signal/!d' -e '/Received signal/q' |
tail -r
GNU 시스템 사용자는 위의 방법 tac
대신 이것을 사용할 수 있습니다 .tail -r
사용해야 한다고 생각되면 awk
위 sed
파이프라인의 명령을 다음으로 바꾸세요.
awk '/Deployment finished/,/Received signal/; /Received signal/ { exit }'
문제의 데이터를 제공하는 출력:
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received message signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Branch is Testing
2023-03-09 11:52:57,195 - Code Deploy - INFO - Deployment started
2023-03-09 11:53:58,246 - Code Deploy - INFO - Old version2_0_5_13
2023-03-09 11:53:58,246 - Code Deploy - INFO - New version2_0_5_14
2023-03-09 11:53:58,498 - Code Deploy - INFO - Permission fixed
2023-03-09 11:53:58,498 - Code Deploy - INFO - Deployment finished
답변3
간단한 방법은 각 일치 항목을 변수에 저장하고 이전 내용을 덮어쓴 다음 스크립트 끝에 변수를 인쇄하는 것입니다.
$ awk '{
if(/Received signal/){k=1; v=$0}
else if(k==1){
v=v RS $0;
if(/Deployment finished/){ k=0 }
}
}
END{ print v }' result.log
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received message signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Branch is Testing
2023-03-09 11:52:57,195 - Code Deploy - INFO - Deployment started
2023-03-09 11:53:58,246 - Code Deploy - INFO - Old version2_0_5_13
2023-03-09 11:53:58,246 - Code Deploy - INFO - New version2_0_5_14
2023-03-09 11:53:58,498 - Code Deploy - INFO - Permission fixed
2023-03-09 11:53:58,498 - Code Deploy - INFO - Deployment finished
또는 tac
파일을 뒤집은 다음 첫 번째 일치 항목을 인쇄할 수 있습니다.
$ tac result.log |
awk '/Deployment finished/,/Received signal/{
print;
if(/Received signal/){ exit }
}' | tac
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received message signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Branch is Testing
2023-03-09 11:52:57,195 - Code Deploy - INFO - Deployment started
2023-03-09 11:53:58,246 - Code Deploy - INFO - Old version2_0_5_13
2023-03-09 11:53:58,246 - Code Deploy - INFO - New version2_0_5_14
2023-03-09 11:53:58,498 - Code Deploy - INFO - Permission fixed
2023-03-09 11:53:58,498 - Code Deploy - INFO - Deployment finished
답변4
사용행복하다(이전 Perl_6)
~$ raku -e 'my $k; my @v; for lines() {
if /Received \s signal/ {$k = 1; @v = $_}
elsif ($k == 1) { @v.push: $_ };
if /Deployment \s finished/ {$k = 0}
}; .put for @v;' file
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Received message signal
2023-03-09 11:52:57,194 - Code Deploy - INFO - Branch is Testing
2023-03-09 11:52:57,195 - Code Deploy - INFO - Deployment started
2023-03-09 11:53:58,246 - Code Deploy - INFO - Old version2_0_5_13
2023-03-09 11:53:58,246 - Code Deploy - INFO - New version2_0_5_14
2023-03-09 11:53:58,498 - Code Deploy - INFO - Permission fixed
2023-03-09 11:53:58,498 - Code Deploy - INFO - Deployment finished
위의 코드는 @terdon의 훌륭한 awk
코드를 뻔뻔하게 따르지만 Raku로 다시 작성되었습니다. @terdon이 지적한 핵심은 공개 정규식이 발견될 @v
때마다 "저장 변수"(이 경우 배열)를 덮어쓰는 것입니다. /Received \s signal/
여기서는 lines
모두 토픽 변수에 하나씩 로드되기 때문에 $_
코드를 사용합니다.@v = $_
/Deployment \s finished/
파일의 끝에 도달했을 때 끝이 보일 때까지 아무것도 반환되지 않도록 하려면 (예: "전체 기록" 요구 사항) 최종 출력 put
문을 다음과 같이 변경하세요.
.put if $k == 0 for @v;
#OR
.put unless $k == 1 for @v;
https://docs.raku.org/언어/control.html#Control_flow
https://raku.org