0

I'm trying to extract a specific line from a .htm file when a pattern occur ("Event 100" in my example below) but at the same time I need to retrieve also another pattern which is related to the first but which comes from one of the lines above it. This second pattern represent the time at which the first pattern occurred:

Example:

<AZ>207994</AZ>
<AZ>09:10:41.9</AZ>
<AZ>02/04</AZ>
<AZ>[990875]</AZ>
<TR VALIGN=TOP>
<AZ>207995</AZ>
<AZ>09:10:56.4</AZ>
<AZ>02/04</AZ>
<AZ>[990876]</AZ>
<AZ>30718</AZ><AZ><!--void--></AZ><AZ><!--void--></AZ><AZ><!--void--></AZ>
<AZ>TN (speed)  Event 3 occurred</TD></TR>
<TR VALIGN=TOP>
<AZ>30719</TD><TD><!--void--></AZ><AZ><!--void--></AZ><AZ><!--void--></AZ>
<AZ>TN (speed)  Event 100 occurred</TD></TR>
<TR VALIGN=TOP>
<AZ>30720</AZ><AZ><!--void--></AZ><AZ><!--void--></AZ><AZ><!--void--></AZ>

I want the following result:

02/04 09:10:56.4 [990876] Event 100 occurred

  • Why print Event 100 occurred rather that Event 3 occurred? – Graeme Apr 8 '14 at 9:11
  • Because I'm interested only in Event 100. The script shall look for the first pattern (Event 100) and then the second (time and date) – John Apr 9 '14 at 4:59
2

I came up with this nasty oneliner (line breaks for readability):

awk -F'[<>]'  '($0 ~ /[0-9][0-9]:[0-9][0-9]:[0-9][0-9]/) {time=$3}
               ($0 ~ /[0-9][0-9]\/[0-9][0-9]/) {date=$3}
               ($0 ~ /\[[0-9]+\]/) {tag=$3}
               ($0 ~ /Event 100 occurred/) { print date, time, tag, "Event 100 occurred"}' < testfile

This consistently collects things that look like a time, a date, or a tag ([12345]), and if a line like "Event 100 occurred" occurs, the current content of the variables is printed. Is that the desired output?

  • I think you need to drop the brackets from the field separator list as these are in the sample output. Otherwise +1. – Graeme Apr 8 '14 at 9:15
  • 1
    I tested it this way, and I need (want) both < and > as field separators, so I use [<>] as a regular expression for the field separator. It doesn't work without them – Jasper Apr 8 '14 at 9:20
  • Ok, or else both < and > would be required for a sepatator, I see. – Graeme Apr 8 '14 at 9:24
  • @Jasper, tks for the answer but it doesn't work.It prints 17 lines as below: Event 100 occurred 09:10:41.9 Event 100 occurred 02/04 09:10:41.9 Event 100 occurred 02/04 09:10:41.9 [990875] Event 100 occurred 02/04 09:10:41.9 [990875] Event 100 occurred 02/04 09:10:56.4 [990875] Event 100 occurred 02/04 09:10:56.4 [990875] Event 100 occurred ... 02/04 09:10:56.4 [990876] Event 100 occurred 02/04 09:10:56.4 [990876] Event 100 occurred <AZ>TN (speed) Event 100 occurred</TD></TR> 02/04 09:10:56.4 [990876] Event 100 occurred 02/04 09:10:56.4 [990876] Event 100 occurred – John Apr 9 '14 at 7:56
  • Can you edit that (including the original file, or a link to it) into your question? It's very hard to read this way. Which output did you expect? – Jasper Apr 9 '14 at 13:59
0

This should do the trick:

(grep -oP "Event 100" file && \
sed -ne 's/<\/\?AZ>//g' -e '7,9p' file) | \
awk 'BEGIN {RS=""; FS="\n";} \
{printf "%s %s %s %s\n", $3, $2, $4, $1}'

Explanation:

  • file: the file that contains you output above
  • grep -oP "Event 100" file: Searches for "Event 100"
  • sed -ne 's/<\/\?AZ>//g' -e '7,9p' file: If the string was found, remove the <AZ> and </AZ> tags, and print the lines 7 to 9
  • awk 'BEGIN {RS=""; FS="\n";}: set awk's field sepatator to newline
  • {printf "%s %s %s %s\n", $3, $2, $4, $1}: and print the output in the desired order

Output (if string is found):

02/04 09:10:56.4 [990876] Event 100

If string is not found there is no output.

  • The point is that you don't actually know where the time and date is. Your script works only for line 7 to 9 but actually could be another because come other events occurres before the line #7 – John Apr 9 '14 at 4:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.