AWK 패턴을 따르는 행을 제외한 특정 행을 필터링하는 방법

AWK 패턴을 따르는 행을 제외한 특정 행을 필터링하는 방법

다음 구조의 로그 파일이 있습니다.

  1. 타임스탬프 헤더
  2. 로그 라인

이러한 파일의 예는 다음과 같습니다.

Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: ---
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: index: 14 timestamp: 1,590,170,100 value: 6
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: delta totalA: 0 total: 5 totalA/total: 0 totalA/total/deltaC.length: 0
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: bA index: 0 p: 294,325 b: 0 bb: 5 a: 0 aa: 0 total: 5
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: positionX: 141 positionY: 39
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: ---
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: index: 14 timestamp: 1,590,170,100 value: 6
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: delta totalA: 0 total: 5 totalA/total: 0 totalA/total/deltaC.length: 0
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: bA index: 0 p: 294,325 b: 0 bb: 5 a: 0 aa: 0 total: 5
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: positionX: 141 positionY: 39

다음 타임스탬프를 제외한 모든 타임스탬프를 제거하고 싶습니다.---

---
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: index: 14 timestamp: 1,590,170,100 value: 6
FINE: delta totalA: 0 total: 5 totalA/total: 0 totalA/total/deltaC.length: 0
FINE: bA index: 0 p: 294,325 b: 0 bb: 5 a: 0 aa: 0 total: 5
FINE: positionX: 141 positionY: 39
---
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: index: 14 timestamp: 1,590,170,100 value: 6
FINE: delta totalA: 0 total: 5 totalA/total: 0 totalA/total/deltaC.length: 0
FINE: bA index: 0 p: 294,325 b: 0 bb: 5 a: 0 aa: 0 total: 5
FINE: positionX: 141 positionY: 39

나는 이것을 시도했습니다 :

cat logFile.txt | awk -F':' '/$2=="---"/ {next; print $0; continue}; !/^FINE/ {next}; {print}'

성공하지 못했습니다.

저는 FreeBSD 12.1을 사용하고 있습니다(csh, 하지만 올바른 도구가 잘못되었으므로 문제가 되지 않을 것 같습니다. 제가 틀렸다면 정정해 주십시오).

답변1

sed는 다음을 수행할 수 있습니다.

$ sed -nE '/---/{s/.*: (-*)/\1/;N;p}; /FINE/p' file
---
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: index: 14 timestamp: 1,590,170,100 value: 6
FINE: delta totalA: 0 total: 5 totalA/total: 0 totalA/total/deltaC.length: 0
FINE: bA index: 0 p: 294,325 b: 0 bb: 5 a: 0 aa: 0 total: 5
FINE: positionX: 141 positionY: 39
---
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: index: 14 timestamp: 1,590,170,100 value: 6
FINE: delta totalA: 0 total: 5 totalA/total: 0 totalA/total/deltaC.length: 0
FINE: bA index: 0 p: 294,325 b: 0 bb: 5 a: 0 aa: 0 total: 5
FINE: positionX: 141 positionY: 39 

/---/패턴이 일치 하는 경우 :

s/.*: (-*)/\1/=> "FINE: ---"를 "---"로 교체
N;p=> 현재 줄을 다음 줄에 추가합니다(예: 다음 날짜 스탬프 줄 추가).

/FINE/p => FINE이 있는 다른 모든 줄은 인쇄됩니다.

또 다른 이상한:

$ awk '/---/ { getline h;$0="---\n"h;print } /^FINE/{print }' file

답변2

$ awk 'p=="FINE: ---" && !/FINE/; {p=$0} /FINE/{sub(/FINE: -/, "-"); print}' ip.txt
---
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: index: 14 timestamp: 1,590,170,100 value: 6
FINE: delta totalA: 0 total: 5 totalA/total: 0 totalA/total/deltaC.length: 0
FINE: bA index: 0 p: 294,325 b: 0 bb: 5 a: 0 aa: 0 total: 5
FINE: positionX: 141 positionY: 39
---
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: index: 14 timestamp: 1,590,170,100 value: 6
FINE: delta totalA: 0 total: 5 totalA/total: 0 totalA/total/deltaC.length: 0
FINE: bA index: 0 p: 294,325 b: 0 bb: 5 a: 0 aa: 0 total: 5
FINE: positionX: 141 positionY: 39
  • {p=$0}현재 줄을 p변수 에 저장합니다.
  • p=="FINE: ---" && !/FINE/이전 행이 FINE: ---현재 행과 일치하지 않는지 확인합니다 FINE. 조건이 충족되면 현재 줄이 인쇄됩니다.
  • /FINE/{sub(/FINE: -/, "-"); print}현재 행에 가 포함된 경우 FINE이 함수는 sub행에서 해당 항목을 제거합니다. 그런 다음 줄을 인쇄하십시오FINE:FINE: ---

다음을 사용할 수도 있습니다.

awk 'p; {p=0} /FINE/{if($2=="---") {print $2; p=1} else print}'
# or using getline, assuming no errors
awk '/FINE/{if($2=="---") {print $2; getline} print}'

답변3

$ awk '/^FINE:/{print (/---$/ ? $2 ORS p : $0)} {p=$0}' file
---
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: index: 14 timestamp: 1,590,170,100 value: 6
FINE: delta totalA: 0 total: 5 totalA/total: 0 totalA/total/deltaC.length: 0
FINE: bA index: 0 p: 294,325 b: 0 bb: 5 a: 0 aa: 0 total: 5
FINE: positionX: 141 positionY: 39
---
Jun 03, 2020 10:39:04 AM pacakge.subpackage.Class method
FINE: index: 14 timestamp: 1,590,170,100 value: 6
FINE: delta totalA: 0 total: 5 totalA/total: 0 totalA/total/deltaC.length: 0
FINE: bA index: 0 p: 294,325 b: 0 bb: 5 a: 0 aa: 0 total: 5
FINE: positionX: 141 positionY: 39

답변4

이것은 freenode에서 제안된 내용으로, 우아하고 읽기 쉽다고 생각합니다.

awk '$1 != "FINE:" {h=$0} $2 == "---" {printf "---\n%s\n", h} $1 == "FINE:" && $2 != "---"'

관련 정보