• print everything after a line matching a pattern

    From Rainer Weikusat@21:1/5 to All on Tue Feb 9 21:10:56 2021
    First use I've ever found for the perl range operator:

    perl -ane '// .. /Reverse Provides/ or print $F[0], "\n"'

    This reads lines from stdin until one matching /Reverse Provides/ is encountered and prints everything line after that.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From George Bouras@21:1/5 to All on Thu Feb 11 10:23:05 2021
    Στις 9/2/2021 11:10 μ.μ., ο/η Rainer Weikusat έγραψε:
    First use I've ever found for the perl range operator:

    perl -ane '// .. /Reverse Provides/ or print $F[0], "\n"'

    perl -ane '$a && print; /foo/ and $a=1'

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to George Bouras on Thu Feb 11 11:34:25 2021
    George Bouras <foo@example.com> writes:

    Στις 9/2/2021 11:10 μ.μ., ο/η Rainer Weikusat έγραψε:
    First use I've ever found for the perl range operator:

    perl -ane '// .. /Reverse Provides/ or print $F[0], "\n"'

    This does not print lines matching the right pattern in the range, so it
    does not do exactly what the subject line says.

    It took me a while to work out what's really going on because the use of
    //, with it's special meaning, makes the whole thing a bit too tricksy
    for me (and I like tricksy!). I'm still not sure what Perl says about
    using m// before any match has succeeded.

    perl -ane '$a && print; /foo/ and $a=1'

    I think this is clearer (though I might use a name like $seen rather
    than $a) and it does do exactly what the subject line says.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rainer Weikusat@21:1/5 to Ben Bacarisse on Thu Feb 11 13:35:02 2021
    Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
    George Bouras <foo@example.com> writes:

    Στις 9/2/2021 11:10 μ.μ., ο/η Rainer Weikusat έγραψε:
    First use I've ever found for the perl range operator:

    perl -ane '// .. /Reverse Provides/ or print $F[0], "\n"'

    This does not print lines matching the right pattern in the range, so it
    does not do exactly what the subject line says.

    The subject says "everything after" and that's what it does: The
    separator is not supposed to be included.

    It took me a while to work out what's really going on because the use of
    //, with it's special meaning, makes the whole thing a bit too tricksy
    for me (and I like tricksy!). I'm still not sure what Perl says about
    using m// before any match has succeeded.

    If no match has previously succeeded, this will (silently) act instead
    as a genuine empty pattern (which will always match).
    [perldoc perlop]

    perl -ane '$a && print; /foo/ and $a=1'

    I think this is clearer (though I might use a name like $seen rather
    than $a) and it does do exactly what the subject line says.

    It's obviously possible to imitate the built-in operator using a
    (miniature) state machine. But as there's a built-in operator which can
    serve the exact same function (and one I haven't found any use for so
    far), I considered this more worth of writing about it.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to Rainer Weikusat on Thu Feb 11 15:42:36 2021
    Rainer Weikusat <rweikusat@talktalk.net> writes:

    Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
    George Bouras <foo@example.com> writes:

    Στις 9/2/2021 11:10 μ.μ., ο/η Rainer Weikusat έγραψε:
    First use I've ever found for the perl range operator:

    perl -ane '// .. /Reverse Provides/ or print $F[0], "\n"'

    This does not print lines matching the right pattern in the range, so it
    does not do exactly what the subject line says.

    The subject says "everything after" and that's what it does: The
    separator is not supposed to be included.

    I think there is some ambiguity in the wording.

    $ cat t
    a
    b
    x
    c
    d
    x
    e
    $ perl -ane '// .. /x/ or print $F[0], "\n"' t ✘
    c
    d
    e
    $

    I assumed you'd want the second x line printed since it follows a match,
    but of course it is also, at the same time, a match itself.

    It took me a while to work out what's really going on because the use of
    //, with it's special meaning, makes the whole thing a bit too tricksy
    for me (and I like tricksy!). I'm still not sure what Perl says about
    using m// before any match has succeeded.

    If no match has previously succeeded, this will (silently) act instead
    as a genuine empty pattern (which will always match).
    [perldoc perlop]

    Ah, thanks. I searched but could not find that. Maybe I only looked
    in perlre.

    perl -ane '$a && print; /foo/ and $a=1'

    I think this is clearer (though I might use a name like $seen rather
    than $a) and it does do exactly what the subject line says.

    It's obviously possible to imitate the built-in operator using a
    (miniature) state machine. But as there's a built-in operator which can
    serve the exact same function (and one I haven't found any use for so
    far), I considered this more worth of writing about it.

    If you want the behaviour that you actually get with //../pattern/ then
    this code is not equivalent. I agree that the state-machine equivalent
    of the original would be messier.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rainer Weikusat@21:1/5 to Ben Bacarisse on Thu Feb 11 16:14:07 2021
    Ben Bacarisse <ben.usenet@bsb.me.uk> writes:

    [...]


    perl -ane '// .. /Reverse Provides/ or print $F[0], "\n"'

    [...]

    perl -ane '$a && print; /foo/ and $a=1'

    I think this is clearer (though I might use a name like $seen rather
    than $a) and it does do exactly what the subject line says.

    It's obviously possible to imitate the built-in operator using a
    (miniature) state machine. But as there's a built-in operator which can
    serve the exact same function (and one I haven't found any use for so
    far), I considered this more worth of writing about it.

    If you want the behaviour that you actually get with //../pattern/ then
    this code is not equivalent. I agree that the state-machine equivalent
    of the original would be messier.

    Thanks for pointing this out: The difference (start printing after the
    first Reverse Provides and omit all later lines containing this text)
    doesn't matter for my use-case but technically, what I wanted was

    1 .. /Reverse Provides/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to Rainer Weikusat on Thu Feb 11 16:35:50 2021
    Rainer Weikusat <rweikusat@talktalk.net> writes:

    Ben Bacarisse <ben.usenet@bsb.me.uk> writes:

    [...]


    perl -ane '// .. /Reverse Provides/ or print $F[0], "\n"'

    [...]

    perl -ane '$a && print; /foo/ and $a=1'

    I think this is clearer (though I might use a name like $seen rather
    than $a) and it does do exactly what the subject line says.

    It's obviously possible to imitate the built-in operator using a
    (miniature) state machine. But as there's a built-in operator which can
    serve the exact same function (and one I haven't found any use for so
    far), I considered this more worth of writing about it.

    If you want the behaviour that you actually get with //../pattern/ then
    this code is not equivalent. I agree that the state-machine equivalent
    of the original would be messier.

    Thanks for pointing this out: The difference (start printing after the
    first Reverse Provides and omit all later lines containing this text)
    doesn't matter for my use-case but technically, what I wanted was

    1 .. /Reverse Provides/

    Now that's a clean use of the range operator. The specific behaviour of
    the original results from a number of somewhat (at least to me)
    unexpected consequences:

    // won't match most lines after /Reverse Provides/ matches because it
    no longer means a literal empty match.

    // will match a following line with 'Reverse Provides', making the
    range expression true again.

    .. (in contrast to ...) immediately tests the right-hand expression as
    well so the range expressions switches to false on the same input
    line.

    But the switch to being false does not take place until the range
    expression is tested again on the next line, so the expression returns
    true exactly once causing the line that opens and closes the range to
    be printed.

    It took me longer that I'd like to admit to work that out, but I must
    thank you for prompting me to study it.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)