views:

69

answers:

4

Hi, I am given a log file(see below), I need to make it to this format using bash script:

title pdfspool date rip date bmpspool date CLAB date Sometitle12 10/09/23 00:56:40 10/9/23 0:56:46 10/9/23 0:56:50 10/9/23 1:01:13

log file


!!Begin    
Source aserver:pdf_spool:the, Job 844b015e0043469e, Inst 844b015e0043469e    
Title Sometitle12.pdf    
Action Started Received, Ok Date 10/09/23 00:56:40    
For Administrator    
(8) DataType = PDF    
(17) Source = srv01:aserver:file_input:0    
!!End    
!!Begin    
Source aserver:rip:rip1, Job 844b015e0043469e, Inst 844b015e004346a0    
Title Sometitle12.pdf Cyan 1    
Action Started Transmit, Ok Date 10/09/23 00:56:46    
For Administrator    
(8) DataType = Bitmap    
(1) Destination = srv01:bserver:bmp_spool:the    
(4) Parent = 844b015e0043469e/844b015e0043469e    
!!End    
!!Begin    
Source bserver:bmp_spool:the, Job 844b015e0043469e, Inst 844b015e004346a0    
Title Sometitle12.pdf Cyan 1    
Action Started Received, Ok Date 10/09/23 00:56:50    
For Administrator    
(8) DataType = Bitmap    
(17) Source = srv01:aserver:rip:rip1    
!!End    
!!Begin    
Source bserver:bmp_spool:the, Job 844b015e0043469e, Inst 844b015e004346a0    
Title Sometitle12.pdf Cyan 1    
Action Atomic Accepted, Ok Date 10/09/23 01:01:13    
For Administrator    
(8) DataType = Bitmap    
(2) Source Queue = ^03Newspaper ltd(MP)^Date - 24MP^Site - N^    
(5) Requested By = clab    
(15) Approval Status = Waiting Approved    
 Changed from Waiting to Approved by clab.   
!!End    

Ideas welcome.

Thanks!

+2  A: 

Use awk. Write a state machine. Switch states when you see /^!!Begin$/, record your data, and dump your output and switch back when you see /^!!End$/.

Ignacio Vazquez-Abrams
A: 

If you use Perl/Python/Ruby, you should able to use regular expression matching in one line (the matching part). Use the multiline mode where a . will match the newline character. I think awk or sed should be able to use regular expression the same way:

for example, in Ruby:

s = <<TEXT
!!Begin
Something haha
Title Good Bad Ugly
Date 1/1/2008
!!End
!!Begin
Other info
Title Iron Man
Date 2/2/2010
TEXT

result = s.scan(/^!!Begin.*?^Title\s+([^\n]*).*?^Date\s+([^\n]*)/m)

p result

result.each do |arr|
  puts arr.join(' ')
end

output:

$ ruby try.rb 
[["Good Bad Ugly", "1/1/2008"], ["Iron Man", "2/2/2010"]]
Good Bad Ugly 1/1/2008
Iron Man 2/2/2010
動靜能量
how do you read text file and pass it to "s" variable here? get_file_as_text didn't work
myschyk
+1  A: 
awk 'BEGIN{}
/Action Started Received/ && !c{ pdfspooldate=$(NF-1)$NF ;c++}
/Action Started Received/ && c{ bmppooldate=$(NF-1)$NF ;c=0}
/Action Started Transmit/{ ripdate=$(NF-1)$NF }
/title/ { title=$2}
/Action Atomic Accepted/{ clabdate=$(NF-1)$NF }
END{ print title,pdfspooldate,ripdate,clabdate }' file
ghostdog74
Thanks! It works great, except that you skipped bmpspool date which has the same pattern as pdfspooldate. How to differentiate them?
myschyk
you can set a counter. See my edit
ghostdog74
How do I parse now a file with multiple pieces of that log?By, the way in the counter I used $c=2 and it worked.
myschyk
A: 

I'd use Perl with $/ = "!!End", then parse each paragraph.

glenn jackman