설명하는 항목이 여러 개 있습니다.이벤트매우 큰 로그 파일에서 다음과 같이 말하십시오.통나무. 나는 두 가지 일을 하고 싶다.이벤트로그 파일의 항목:
- 각 항목의 발생 횟수를 계산합니다. (필수사항은 아니지만 있으면 좋을 것 같습니다.)
- 실제 항목을 별도의 파일로 추출하고 나중에 연구하십시오.
일반적인 이벤트 항목은 다음과 같으며 항목 사이에 추가 텍스트가 있습니다. 따라서 아래 예에는 두 가지가 있습니다.이벤트항목 중 첫 번째 항목에는 두 개의 DataChangeEntry
페이로드가 포함되고 두 번째 항목에는 하나의 DataChangeEntry
페이로드가 포함됩니다.
Data control raising event :DataControl@263c015d[[
#### DataChangeEvent #### on [DataControl name=PatternMatch_LegendTimeAxis, binding=.dynamicRegion1. beam_project_PatternMatch_dashboard_LegendTimeAxis_taskflow_LegendTimeAxis_beamDashboardLegendTimeAxisPageDef_beam_project_PatternMatch_dashboard_LegendTimeAxis_taskflow_LegendTimeAxis_beamDashboardLegendTimeAxis_xml_ps_taskflowid.dynamicRegion58. beam_project_PatternMatch_view_LegendTimeAxis_taskflow_LegendTimeAxis_beamVizLegendTimeAxisPageDef_beam_project_PatternMatch_view_LegendTimeAxis_taskflow_LegendTimeAxis_beamVizLegendTimeAxis_xml_ps_taskflowid.QueryIterator]
Filter/Collection Id : 0
Collection Level : 0
Sequence Id : 616
ViewSetId : PatternMatch.LegendTimeAxis_V1_0_SN49
==== DataChangeEntry (#1)
ChangeType : UPDATE
KeyPath : [2014-06-26 06:15:00.0, 0]
AttributeNames : [DATAOBJECT_CREATED, COUNTX, QueryName]
AttributeValues : [2014-06-26 06:15:00.0, 11, StrAvgCallWaitTimeGreaterThanThreshold]
AttributeTypes : [java.sql.Timestamp, java.lang.Integer, java.lang.String, ]
==== DataChangeEntry (#2)
ChangeType : UPDATE
KeyPath : [2014-06-26 06:15:00.0, 0]
AttributeNames : [DATAOBJECT_CREATED, COUNTX, QueryName]
AttributeValues : [2014-06-26 06:15:00.0, 9, AverageCallWaitingTimeGreateThanThreshold]
AttributeTypes : [java.sql.Timestamp, java.lang.Integer, java.lang.String, ]
]]
someother non useful text
spanning multiple lines
Data control raising event :DataControl@263c015d[[
#### DataChangeEvent #### on [DataControl name=PatternMatch_LegendTimeAxis, binding=.dynamicRegion1. beam_project_PatternMatch_dashboard_LegendTimeAxis_taskflow_LegendTimeAxis_beamDashboardLegendTimeAxisPageDef_beam_project_PatternMatch_dashboard_LegendTimeAxis_taskflow_LegendTimeAxis_beamDashboardLegendTimeAxis_xml_ps_taskflowid.dynamicRegion58. beam_project_PatternMatch_view_LegendTimeAxis_taskflow_LegendTimeAxis_beamVizLegendTimeAxisPageDef_beam_project_PatternMatch_view_LegendTimeAxis_taskflow_LegendTimeAxis_beamVizLegendTimeAxis_xml_ps_taskflowid.QueryIterator]
Filter/Collection Id : 0
Collection Level : 0
Sequence Id : 616
ViewSetId : PatternMatch.LegendTimeAxis_V1_0_SN49
==== DataChangeEntry (#1)
ChangeType : UPDATE
KeyPath : [2014-06-26 06:15:00.0, 0]
AttributeNames : [DATAOBJECT_CREATED, COUNTX, QueryName]
AttributeValues : [2014-06-26 06:15:00.0, 11, StrAvgCallWaitTimeGreaterThanThreshold]
AttributeTypes : [java.sql.Timestamp, java.lang.Integer, java.lang.String, ]
]]
==== DataChangeEntry
이벤트 항목의 행 수는 가변적일 수 있습니다. 또한 완전히 없을 수도 있습니다. 이는 이벤트 페이로드가 비어 있고 오류 조건임을 나타내며, 이 경우도 확실히 파악하고 싶을 것입니다.
이 경우 항목의 출력이 여러 줄에 걸쳐 있기 때문에 일반 grep을 사용하여 멀리 가지 못했습니다. 그래서 전문가의 조언을 구하고 있습니다.
첨부된:
- 내 요구 사항에 대해 더 명확하게 설명하겠습니다. 위에 표시된 전체 텍스트 블록을 그대로 캡처하고 선택적으로 해당 블록이 발생한 인스턴스 수를 계산하고 싶습니다. 인스턴스 수를 계산하는 옵션은 좋지만 필수는 아닙니다.
- 문제의 해결 방법이 awk를 사용하는 것이라면 awk 파일을 저장해서 재사용하고 싶습니다. 따라서 스크립트를 실행하는 단계도 언급해 주세요. 나는 regex와 grep을 알고 있지만 sed 및/또는 awk에는 익숙하지 않습니다.
답변1
나는 이것이 이루어질 수 있기를 바랍니다. 이벤트는 파일에 저장됩니다 events
. 메시지는 표준 출력으로 전송됩니다.
이 파일을 myprogram.awk에 저장합니다(예:).
#!/usr/bin/awk -f
BEGIN {
s=0; ### state. Active when parsing inside an event
nevent=0; ### Current event number
printf "" > "events"
}
# Start of event
/^ *Data control raising event/ {
s=1;
dentries=0;
print "*** Event number: " nevent >> "events"
nevent++
}
# Standard event line
s==1 {
print >> "events"
}
# DataChangeEntry line
/^ *==== DataChangeEntry/ {
dentries ++
}
# End of event
s==1 && /^ *\]\]/ {
s=0;
print "" >> "events"
if(dentries==0){
print "Warning: Event " nevent " has no Data Entries"
}
}
END {
print "Total event count: " nevent
}
다양한 방법으로 호출할 수 있습니다.
myprogram.awk inputfile.txt
awk -f myprogram.awk inputfile.txt
예제 출력:
Warning: Event 3 has no Data Entries
Total event count: 3
작업 디렉터리에 있는 파일에서 모든 이벤트를 함께 검사할 수 있습니다 events
.
답변2
아주 간단한 방법은
awk '{print > NR".entry"}END{print NR" entries"}' RS="]]" file
그러면 각 항목에 대해 별도의 파일이 생성되고 발견된 항목 수가 표준 출력으로 인쇄됩니다.
설명하다
NR
의 현재 줄 번호입니다awk
.RS="]]"
레코드 구분 기호("행"을 정의하는 것)를 로 설정합니다]]
. 이는 각 항목이 행으로 처리됨을 의미합니다awk
.{print > NR".entry"}
: 현재 줄(항목)을 이름이 지정된 줄에 인쇄하므로[LineNumber].entry
첫1.entry
번째,2.entry
두 번째 등이 포함됩니다.END{print NR" entries"}
: 입력 파일 전체를 처리한 후 END 블록을 실행합니다. 따라서 이 시점에서는NR
처리된 항목 수가 됩니다.
별칭으로 저장하거나 다음과 같은 스크립트에 넣을 수 있습니다.
#!/usr/bin/env bash
awk '{print > NR".entry"}END{print NR" entries"}' RS="]]" "$1"
foo.sh
그런 다음 대상 파일을 인수로 사용하여 스크립트를 실행할 수 있습니다(이 파일이 호출되고 $PATH에 있다고 가정).
foo.sh file
출력 파일 이름을 조정할 수도 있습니다. 예를 들어 파일을 로드하려면 [date].[entry number].[entry]
다음 명령을 사용합니다.
#!/usr/bin/env bash
date=$(date +%Y%m%d)
awk '{print > d"."NR".entry"}END{print NR" entries"}' RS="]]" d="$date" "$1"
위의 내용은 로그 파일에 "이벤트" 항목만 포함되어 있다고 가정합니다. 그렇지 않고 무시해야 하는 다른 행이 있을 수 있는 경우 대신 다음을 사용하십시오.
#!/usr/bin/env bash
date=$(date +%Y%m%d)
awk '{
if(/\[\[/){a=1; c++;}
if(/\]\]/){a=0; print > d"."c".entry"}
if(a==1){print >> d"."c".entry"}
}' d="$date" file
또는 문장으로:
awk '{if(/\[\[/){a=1; c++;}if(/\]\]/){a=0; print > d"."c".entry"}if(a==1){print >> d"."c".entry"}}' d=$(date +%Y%m%d) file