From: thdyoung on
On Jul 13, 2:13 pm, Ben Bacarisse <ben.use...(a)bsb.me.uk> wrote:
> Ed Morton <mortons...(a)gmail.com> writes:
> > On 7/13/2010 1:32 AM, moonhkt wrote:
> >> How to grep multi-line, when input particlar date ?
>
> >> Text file
> >> 2010/06/21 Canon Scanner 9000F
Could a kind person speak what this code means ?

I see: announcement of a variable and a value assigned to it
Then a 'pattern' - posix digits at the start of the line
Then the 'action' which I can't read. It seems to announce another
variable f which, I think, is conditional on the first field being the
date
Then f outside the last curly brace followed by the input

Sorry to be thick but this seems to say ' print f (a line of input) if
the first field of f (guessing really) is the date d '

Probably this is wrong coz I've haven't given an account of what the
regex pattern is doing except note that it demands a number at the
start of the line...

thanks

Tom

>

>> 2010/06/30 MacBook Pro Delivery, Original 2010/07/02
> >>             S/N
> >>             etc...
> >> 2010/07/06 Mail Rebate Form to MAC Apple,http://www.apple.com/hk/promo/rebate/bts.html
> <snip>
> > Try this (untested):
>
> > awk -v d="2010/07/06" '$0 ~ /^[[:digit:]]/ {f = ($1 == d)} f' file
>
> Is there a reason to prefer "$0 ~ /^[[:digit:]]/" over the simpler
> "/^[[:digit:]]/" as the pattern?
>
> --
> Ben.

From: Ben Bacarisse on
[I've re-ordered an snipped.]

"thdyoung(a)googlemail.com" <thdyoung(a)gmail.com> writes:

> On Jul 13, 2:13 pm, Ben Bacarisse <ben.use...(a)bsb.me.uk> wrote:
>> Ed Morton <mortons...(a)gmail.com> writes:
>> > On 7/13/2010 1:32 AM, moonhkt wrote:
>> >> How to grep multi-line, when input particlar date ?
>>
>> >> Text file
>> >> 2010/06/21 Canon Scanner 9000F
> >> 2010/06/30 MacBook Pro Delivery, Original 2010/07/02
>> >>             S/N
>> >>             etc...
>> >> 2010/07/06 Mail Rebate Form to MAC Apple,http://www.apple.com/hk/promo/rebate/bts.html
>> <snip>
>> > Try this (untested):
>>
>> > awk -v d="2010/07/06" '$0 ~ /^[[:digit:]]/ {f = ($1 == d)} f' file
>>

> Could a kind person speak what this code means ?

Let's start with my suggestion of getting rid of "$0 ~" -- it's less to
explain:

awk -v d="2010/07/06" '/^[[:digit:]]/ {f = ($1 == d)} f' file

awk is passed four arguments: The first two set the variable d to the
desired date. The third is the awk program and the fourth is the file
to process.

awk programs are a sequence of <test> {<action>} pairs (functions are
different but this program has none). You can leave out either the
<test> part or the {<action>} part. The <test> is evaluated against
every line: if the line produces a true result from the test the actions
are executed. If there is no {<action>} part awk assumes {print}, and
if there is no <test> part awk assumes 1 (a test that is always true).

This program has two such pairs which are (after inserting the default
print action):

/^[[:digit:]]/ {f = ($1 == d)}
f {print}

The first matches lines that start with a digit. Such a line sets f to
the value of the test $1 == d. $1 is the first field on the line, so f
gets set to true or false (actually 1 or 0) depending on whether the
line starts with the date that we want (the value of d set on the
command line).

All lines (including this one) are tested against the test f. This is
true (non-zero) or false (zero) depending on what has happened before.
Once f has been set to 1, lines are printed until f gets set to false.
This can happen only when a line is processed that starts with a digit
but has $1 not equal to the date we want.

Ed's original $0 ~ /.../ version is the same. ~ is the match operator
and $0 is the whole line. A pattern on its own is equivalent to a match
against $0.

<snip>
--
Ben.
From: Janis Papanagnou on
On 14/07/10 00:11, thdyoung(a)googlemail.com wrote:
> On Jul 13, 2:13 pm, Ben Bacarisse <ben.use...(a)bsb.me.uk> wrote:
>> Ed Morton <mortons...(a)gmail.com> writes:
>>> On 7/13/2010 1:32 AM, moonhkt wrote:
>>>> How to grep multi-line, when input particlar date ?
>>
>>>> Text file
>>>> 2010/06/21 Canon Scanner 9000F
> Could a kind person speak what this code means ?
>
> I see: announcement of a variable and a value assigned to it
> Then a 'pattern' - posix digits at the start of the line
> Then the 'action' which I can't read. It seems to announce another
> variable f which, I think, is conditional on the first field being the
> date
> Then f outside the last curly brace followed by the input
>
> Sorry to be thick but this seems to say ' print f (a line of input) if
> the first field of f (guessing really) is the date d '
>
> Probably this is wrong coz I've haven't given an account of what the
> regex pattern is doing except note that it demands a number at the
> start of the line...

Reformatted and added the default action...

$0 ~ /^[[:digit:]]/ {f = ($1 == d)}
f { print $0 }

First line:
whenever a line starts with a digit,
evaluate whether the first field equals the requested date,
if so then the flag is set to true (1) otherwise false (0).
Second line:
if flag is set print the line


Actually Ed's code is a variant of the one I posted earlier this morning,
which I explain as well for comparison. The code was

(!/^ / && f=($1~d)) || (f && /^ /)

Reformatted, slightly rearranged, and default action added gives

!/^ / && f=($1~d) { print $0 }
/^ / && f { print $0 }

First line:
whenever a line starts not with white space,
and the flag is set, which depends on
the first field matches the date,
print the line
Second line:
whenever a line starts with white space,
and the flag is set,
print the line


Janis

>
> thanks
>
> Tom
>
>>
>
> >> 2010/06/30 MacBook Pro Delivery, Original 2010/07/02
>>>> S/N
>>>> etc...
>>>> 2010/07/06 Mail Rebate Form to MAC Apple,http://www.apple.com/hk/promo/rebate/bts.html
>> <snip>
>>> Try this (untested):
>>
>>> awk -v d="2010/07/06" '$0 ~ /^[[:digit:]]/ {f = ($1 == d)} f' file
>>
>> Is there a reason to prefer "$0 ~ /^[[:digit:]]/" over the simpler
>> "/^[[:digit:]]/" as the pattern?
>>
>> --
>> Ben.
>

From: moonhkt on
On Jul 14, 6:46 am, Janis Papanagnou <janis_papanag...(a)hotmail.com>
wrote:
> On 14/07/10 00:11, thdyo...(a)googlemail.com wrote:
>
>
>
>
>
> > On Jul 13, 2:13 pm, Ben Bacarisse <ben.use...(a)bsb.me.uk> wrote:
> >> Ed Morton <mortons...(a)gmail.com> writes:
> >>> On 7/13/2010 1:32 AM, moonhkt wrote:
> >>>> How to grep multi-line, when input particlar date ?
>
> >>>> Text file
> >>>> 2010/06/21 Canon Scanner 9000F
> > Could a kind person speak what this code means ?
>
> > I see: announcement of a variable and a value assigned to it
> > Then a 'pattern' - posix digits at the start of the line
> > Then the 'action' which I can't read. It seems to announce another
> > variable f which, I think, is conditional on the first field being the
> > date
> > Then f outside the last curly brace followed by the input
>
> > Sorry to be thick but this seems to say ' print f (a line of input) if
> > the first field of f (guessing really)  is the date d '
>
> > Probably this is wrong coz I've haven't given an account of what the
> > regex pattern is doing except note that it demands a number at the
> > start of the line...
>
> Reformatted and added the default action...
>
>   $0 ~ /^[[:digit:]]/  {f = ($1 == d)}
>   f                    { print $0 }
>
> First line:
>   whenever a line starts with a digit,
>   evaluate whether the first field equals the requested date,
>   if so then the flag is set to true (1) otherwise false (0).
> Second line:
>   if flag is set print the line
>
> Actually Ed's code is a variant of the one I posted earlier this morning,
> which I explain as well for comparison. The code was
>
>   (!/^ / && f=($1~d)) || (f && /^ /)
>
> Reformatted, slightly rearranged, and default action added gives
>
>  !/^ / && f=($1~d)  { print $0 }
>  /^ /  && f         { print $0 }
>
> First line:
>   whenever a line starts not with white space,
>   and the flag is set, which depends on
>   the first field matches the date,
>   print the line
> Second line:
>   whenever a line starts with white space,
>   and the flag is set,
>   print the line
>
> Janis
>
>
>
>
>
> > thanks
>
> > Tom
>
> >  >> 2010/06/30 MacBook Pro Delivery, Original 2010/07/02
> >>>>             S/N
> >>>>             etc...
> >>>> 2010/07/06 Mail Rebate Form to MAC Apple,http://www.apple.com/hk/promo/rebate/bts.html
> >> <snip>
> >>> Try this (untested):
>
> >>> awk -v d="2010/07/06" '$0 ~ /^[[:digit:]]/ {f = ($1 == d)} f' file
>
> >> Is there a reason to prefer "$0 ~ /^[[:digit:]]/" over the simpler
> >> "/^[[:digit:]]/" as the pattern?
>
> >> --
> >> Ben.- Hide quoted text -
>
> - Show quoted text -- Hide quoted text -
>
> - Show quoted text -

Thank a lot
Following coding tested OK.

#!/bin/ksh
file=sch_mail.sch
#awk -v d="2010/06/30" '$0 ~ /^[[:digit:]]/ {f = ($1 == d)} f' $file
#awk -v d="2010/06/30" '(!/^ / && f=($1~d)) || (f && /^ /)' $file
awk -v d="2010/06/30" '
!/^ / && f=($1~d) { print $0 }
/^ / && f { print $0 }
' $file

From: thdyoung on
Thank you Janis for a clear explanation. I get your first line.

Second line: how is 'f' set ? Does it have a default when called ?

Is ' f ' some kind of standard usage in awk ?

Tom

> Reformatted, slightly rearranged, and default action added gives
>
>  !/^ / && f=($1~d)  { print $0 }
>  /^ /  && f         { print $0 }
>
> First line:
>   whenever a line starts not with white space,
>   and the flag is set, which depends on
>   the first field matches the date,
>   print the line
> Second line:
>   whenever a line starts with white space,
>   and the flag is set,
>   print the line
>
> Janis