awk multiline problem
Have been trying to write an awk script which processes a log file, but am struggling.
I have a file which has lines which look like this:
[2011-07-29 04:44:37.100 INFO] AU/SUB1/Server:WebHits : Hits[ABC]=0; Hits[DEF]=876; Hits[THY]=0; Hits[SG]=891; Hits[XFRR]=1386
[2011-07-29 04:44:37.599 INFO] AU/SUB2/Server:WebHits : Hits[XARR]=0; Hits[XXX]=0; Hits[ABS]=0; Hits[SM]=0
[2011-07-29 04:44:37.699 INFO] AU/MAIN/Server:Main : Hits=254
[2011-07-29 04:44:38.100 INFO] AU/SUB1/Server:WebHits : Hits[ABC]=0; Hits[DEF]=1134; Hits[THY]=0; Hits[SG]=1153; Hits[XFRR]=426
[2011-07-29 04:44:38.599 INFO] AU/SUB2/Server:WebHits : Hits[XARR]=0; Hits[XXX]=0; Hits[ABS]=0; Hits[SM]=22
[2011-07-29 04:44:38.699 INFO] AU/MAIN/Server:Main : Hits=436
As you can see there are three lines per second (there will always be three lines per second). I would like to combine these lines (one line per second), so that a 开发者_StackOverflowsummary would look like this, so one line of summary correlators to three lines from the input log file:
[2011-07-29 04:44:37 INFO] MainHits=254,ABC=0,DEF=876,THY=0,SG=891,XFRR=1386,XARR=0,XXX=0,ABS=0,SM=0
[2011-07-29 04:44:38 INFO] MainHits=436,ABC=0,DEF=1134,THY=0,SG=1153,XFRR=426,XARR=0,XXX=0,ABS=0,SM=22
Please note the venue names e.g. "ABC,DEF,THY,SG etc" can change dynamically.
Any help would be appreciated.
The solution relies heavily on the input format you've posted:
awk '/Main :/ {
sub(/\.[0-9]*/, x, $2)
print $1, $2, $3, "Main" $NF, r
r = x; next
}
{
gsub(/Hits\[/, x)
gsub(/[];]/, x)
for (i = 5; ++i <= NF;)
r = r ? r "," $i : $i
}' infile
A cryptic solution using sed:
sed -e 'N;N;s/\n\[.\{28\}\]/;/g;s/\.... INFO/ INFO/;s!AU/SUB1/Server:WebHits : !!;s!AU/SUB2/Server:WebHits : !!;s!AU/MAIN/Server:Main : !!;s/ INFO\] \(.*\) Hits=\(.*\)/ INFO\] MainHits=\2 \1/;s/ Hits\[\([^]]*\)\]=\([^;]*\);/,\1=\2/g' infile
This deserves some explanations, so bellow is a commented script file version . It must be run with 'sed -f script infile'
# Read 2 more lines, so we will have 3 lines are in the pattern space.
N
N
# Change the timestamps of the 2 extra lines by a ;.
s/\n\[.\{28\}\]/;/g
# Remove the milliseconds of the remaining timestamp, and the extra data of each line.
s/\.... INFO/ INFO/
s!AU/SUB1/Server:WebHits : !!
s!AU/SUB2/Server:WebHits : !!
s!AU/MAIN/Server:Main : !!
# Generate the MainHits data.
s/ INFO\] \(.*\) Hits=\(.*\)/ INFO\] MainHits=\2 \1/
# Format the Hits data.
s/ Hits\[\([^]]*\)\]=\([^;]*\);/,\1=\2/g
精彩评论