Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

first post, matching, backing up, and matching forward again.

Status
Not open for further replies.

s0ylgr3n

Technical User
Feb 19, 2009
4
I have a file of test data where I need to match on a pattern and then back up x number of lines (it varies) to match on the date/time stamp and then I need to continue to go forward in the text block until I match on the first blank line or in this case a hex pattern of
0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A.

What I have so far is:

awk '{a[NR]=$0}/pattern/{print a[NR-15]}' /path/to/input

This matches on the pattern and backs up to the date/time stamp and outputs it to std out.

But the lines between the match and backing up to the date/time stamp are always a different number of lines.

I think what I need is a variation of this command:

awk '/match_on_test_data/,/match_on_hex_pattern_at_end_text_block/' /path/to/input

awk '{a[NR]=$0}/match_on_test_data/{print a[NR-15]}' /path/to/input

but I need to make the above "[NR-15]" into a loop that loops up until it matches on the date/time stamp. I searched for a loop structure that might work but so far have not been successful.

File structure is sort of like this:

Sat Jan 31 01:56:15 2009(abcd .... wxyz)test_has_passed(abcd .... wxyz)
&
Sat Jan 31 01:57:41 2009(abcd .... wxyz)test_has_passed(abcd .... wxyz)
&
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(abcd .... wxyz)
(abcd .... wxyz)
Sat Jan 31 01:58:24 2009
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
wq15 HAS FAILED "i want to match on wq15"
(abcd .... wxyz)
(abcd .... wxyz)
(abcd .... wxyz)
(abcd .... wxyz)
(abcd .... wxyz)
(abcd .... wxyz)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(abcd .... wxyz)
(abcd .... wxyz)
(abcd .... wxyz)
(abcd .... wxyz)
0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A.

&
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(abcd .... wxyz)
Fri Jan 30 09:53:26 2009
(abcd .... wxyz)
(abcd .... wxyz)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Failed (abcd .... wxyz)
(abcd .... wxyz)
wq15 there's another wq15 to match at the bottom
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Failed (abcd .... wxyz)
(abcd .... wxyz)
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
(abcd .... wxyz)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Failed (abcd .... wxyz)
(abcd .... wxyz)
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
wq15
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Any help is appreciated ... my remaining hair thanks you.




 
If all you care about is the timestamp to be output whenever your pattern matches, then just keep the last recognized timestamp in a variable of its own and print it when you get your pattern.

Something like:

/^... ... .. ..:..:.. ..../ { #adjust RE to match better
#if your data might match too
LastTime = $0
}

/pattern/ {
printf("%s %s\n",LastTime,$0)
}

 
I forgot to add "next"'s to skip other lines, so add "next" before each closing brace, and add

{
next
}

to skip other lines.
 
Thanks for reply.
I tested the date/time stamp match and it works on the
console.

awk '/^(... ... .. ..:..:.. ....[\x0D/])/' /path/to/input

I tested the /test_data/,/end_of_text_block_char/ /path/to/input, and it works on the console.

awk '/test_data/,/end_of_text_block_char/' /path/to/input

I think I have either a syntax error or a problem with the
ordering of commands. When I run the code as a block, I
don't get any output at all.

awk -f code_block.awk /path/to/input

code_block.awk follows
{
/^(... ... .. ..:..:.. ....[\x0D/])/
LastTime = $0
next
}
/wq15/,/%/
{
printf("%s %s\n",LastTime,$0)
next
}

Thanks for any help,
~

 
# code_block.awk
# match the timestamp
#
# Sample:
# Sat Jan 31 01:56:15 2009(abcd .... wxyz)test_has_passed(abcd .... wxyz)
match($0,/^... ... .. ..:..:.. ..../) {
sub("\r\n","")
LastTime = substr($0,RSTART,RLENGTH)
next
}

# print lines found with wq15 until blank or 0D 0A ...
#
# output includes line with wq15, but replaces 0D 0A ... with blank when detected.
#
# if another wq15 detected without blank line or 0D 0A ..., then insert blank line too.
/wq15/, (/^[ \t\r\n]*$/ || /0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A/) {
sub("\r\n","")
if(match($0, /^[ \t\r\n]*$/) || match($0,/0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A/) ) {
printf("\n");
Needblank = 0
} else if(match($0,/wq15/)) {
if(Needblank) printf("\n")
Needblank = 1
printf("%s: %s\n",LastTime,$0)
} else {
printf("%s: %s\n",LastTime,$0)
}
}

{
next
}

produces the following output from your input provided:

Sat Jan 31 01:58:24 2009: wq15 HAS FAILED "i want to match on wq15"
Sat Jan 31 01:58:24 2009: (abcd .... wxyz)
Sat Jan 31 01:58:24 2009: (abcd .... wxyz)
Sat Jan 31 01:58:24 2009: (abcd .... wxyz)
Sat Jan 31 01:58:24 2009: (abcd .... wxyz)
Sat Jan 31 01:58:24 2009: (abcd .... wxyz)
Sat Jan 31 01:58:24 2009: (abcd .... wxyz)
Sat Jan 31 01:58:24 2009: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Sat Jan 31 01:58:24 2009: (abcd .... wxyz)
Sat Jan 31 01:58:24 2009: (abcd .... wxyz)
Sat Jan 31 01:58:24 2009: (abcd .... wxyz)
Sat Jan 31 01:58:24 2009: (abcd .... wxyz)

Fri Jan 30 09:53:26 2009: wq15 there's another wq15 to match at the bottom
Fri Jan 30 09:53:26 2009: two letters_and_two numbers
Fri Jan 30 09:53:26 2009: two letters_and_two numbers
Fri Jan 30 09:53:26 2009: two letters_and_two numbers
Fri Jan 30 09:53:26 2009: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Fri Jan 30 09:53:26 2009: Failed (abcd .... wxyz)
Fri Jan 30 09:53:26 2009: (abcd .... wxyz)
Fri Jan 30 09:53:26 2009: two letters_and_two numbers
Fri Jan 30 09:53:26 2009: two letters_and_two numbers
Fri Jan 30 09:53:26 2009: two letters_and_two numbers
Fri Jan 30 09:53:26 2009: two letters_and_two numbers
Fri Jan 30 09:53:26 2009: two letters_and_two numbers
Fri Jan 30 09:53:26 2009: two letters_and_two numbers
Fri Jan 30 09:53:26 2009: two letters_and_two numbers
Fri Jan 30 09:53:26 2009: two letters_and_two numbers
Fri Jan 30 09:53:26 2009: two letters_and_two numbers
Fri Jan 30 09:53:26 2009: two letters_and_two numbers
Fri Jan 30 09:53:26 2009: (abcd .... wxyz)
Fri Jan 30 09:53:26 2009: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Fri Jan 30 09:53:26 2009: Failed (abcd .... wxyz)
Fri Jan 30 09:53:26 2009: (abcd .... wxyz)
Fri Jan 30 09:53:26 2009: two letters_and_two numbers
Fri Jan 30 09:53:26 2009: two letters_and_two numbers
Fri Jan 30 09:53:26 2009: two letters_and_two numbers
Fri Jan 30 09:53:26 2009: two letters_and_two numbers
Fri Jan 30 09:53:26 2009: two letters_and_two numbers
Fri Jan 30 09:53:26 2009: two letters_and_two numbers
Fri Jan 30 09:53:26 2009: two letters_and_two numbers

Fri Jan 30 09:53:26 2009: wq15
Fri Jan 30 09:53:26 2009: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

 
Thanks for help. I should have included the desired output.
I have worked on trying to understand my awk script better.
Your examples have helped tremendously. I'm hoping you can
help me understand how to print the time stamp data only
once per every unique match. But your help this far has
been extremely appreciated.
Thanks again.

(example of desired output)
Sat Jan 31 01:58:24 2009:
wq15 HAS FAILED "i want to match on wq15"
(abcd .... wxyz)
(abcd .... wxyz)
(abcd .... wxyz)
(abcd .... wxyz)
(abcd .... wxyz)
(abcd .... wxyz)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(abcd .... wxyz)
(abcd .... wxyz)
(abcd .... wxyz)
(abcd .... wxyz)

Fri Jan 30 09:53:26 2009:
wq15 there's another wq15 to match at the bottom
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Failed (abcd .... wxyz)
(abcd .... wxyz)
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
(abcd .... wxyz)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Failed (abcd .... wxyz)
(abcd .... wxyz)
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers
two letters_and_two numbers

wq15
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


 
# code_block.awk
#
# modified to output timestamp once per matching block
#
# match the timestamp
#
# Sample:
# Sat Jan 31 01:56:15 2009(abcd .... wxyz)test_has_passed(abcd .... wxyz)
match($0,/^... ... .. ..:..:.. ..../) {
sub("\r\n","")
LastTime = substr($0,RSTART,RLENGTH)
PrintTime = 1
next
}

# print lines found with wq15 until blank or 0D 0A ...
#
# output includes line with wq15, but replaces 0D 0A ... with blank when detected.
#
# if another wq15 detected without blank line or 0D 0A ..., then insert blank line too.
/wq15/, (/^[ \t\r\n]*$/ || /0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A/) {
# print time if needed
if(PrintTime) printf("%s\n",LastTime)
PrintTime = 0

# remove carriage returns and linefeeds
sub("\r\n","")

# remove leading blanks
sub("^[ \t]*","")

# look for terminating line (blank, or 0D 0A 0D 0A ...)
if(match($0, /^[ \t\r\n]*$/) || match($0,/0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A/) ) {
printf("\n");
Needblank = 0
} else if(match($0,/wq15/)) {

# if another beginning pattern detected, begin new output block
if(Needblank) {
printf("\n")
printf("%s\n",LastTime)
}
Needblank = 1
printf("%s\n",$0)
} else {

# otherwise, just print the line
printf("%s\n",$0)
}
}

{
next
}
 
It works flawlessly. I can't thank you enough for your help.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top