Matching Line After Pattern (Pattern Occurs Multiple Times) - Unix

This is a discussion on Matching Line After Pattern (Pattern Occurs Multiple Times) - Unix ; Hello, I have a sorted list that contains dates: 1/1/2005 1/1/2005 1/8/2005 1/10/2005 1/10/2005 1/10/2005 1/15/2005 1/21/2005 1/21/2005 I need a one liner that matches the line after the last occurance of the pattern to the end of the file. ...

+ Reply to Thread
Results 1 to 6 of 6

Thread: Matching Line After Pattern (Pattern Occurs Multiple Times)

  1. Matching Line After Pattern (Pattern Occurs Multiple Times)

    Hello, I have a sorted list that contains dates:

    1/1/2005
    1/1/2005
    1/8/2005
    1/10/2005
    1/10/2005
    1/10/2005
    1/15/2005
    1/21/2005
    1/21/2005


    I need a one liner that matches the line after the last occurance of
    the pattern to the end of the file. So in the example if the regex was
    1\/10\/2005, it would match after the 3rd occurence of 1/10/2005; the
    output would contain 3 lines starting at 1/15/2005.

    I have tried: sed '1,'1\/10\/2005'/d, but that prints the 2nd occurance
    to the end of the file. I have also looked around the newsgroups and
    have seen similar functionality in AWK, GREP and PERL, but I have not
    stumbled into the solution.

    I would appreciate it if you could point me in the right direction.

    TIA


  2. Re: Matching Line After Pattern (Pattern Occurs Multiple Times)

    REW wrote:
    > Hello, I have a sorted list that contains dates:
    >
    > 1/1/2005
    > 1/1/2005
    > 1/8/2005
    > 1/10/2005
    > 1/10/2005
    > 1/10/2005
    > 1/15/2005
    > 1/21/2005
    > 1/21/2005
    >
    >
    > I need a one liner that matches the line after the last occurance of
    > the pattern to the end of the file. So in the example if the regex was
    > 1\/10\/2005, it would match after the 3rd occurence of 1/10/2005; the
    > output would contain 3 lines starting at 1/15/2005.
    >
    > I have tried: sed '1,'1\/10\/2005'/d, but that prints the 2nd occurance
    > to the end of the file. I have also looked around the newsgroups and
    > have seen similar functionality in AWK, GREP and PERL, but I have not
    > stumbled into the solution.
    >
    > I would appreciate it if you could point me in the right direction.


    Key insight is split on your regex pattern, and the last segment is what
    you want. So,
    a=`< file`
    set -- "${a|-1/10/2005}"
    echo "${*|[-1]}"

    Or,
    csplit file '/^1\/10\/2005/+1' '{*}'
    and the last xx* file is what you want.

    --
    William Park , Toronto, Canada
    ThinFlash: Linux thin-client on USB key (flash) drive
    http://home.eol.ca/~parkw/thinflash.html
    BashDiff: Super Bash shell
    http://freshmeat.net/projects/bashdiff/

  3. Re: Matching Line After Pattern (Pattern Occurs Multiple Times)

    William, thanks for the reply. Forgive me, I'm still at a loss. When I
    cut and paste your first solution (from a bash command line and from a
    /bin/sh shell script) I get: ./test-script: 3: Syntax error: Bad
    substitution.

    For the second suggestion, I do not have csplit on my FreeBSD box. I do
    have split and a -p option for a pattern. I tried various combination
    of your suggestion but either got a usage prompt or no output.

    I would appreciate further insight on you suggestions.

    Thanks for your help.
    Regards,
    Bob


  4. Re: Matching Line After Pattern (Pattern Occurs Multiple Times)

    REW wrote:
    > William, thanks for the reply. Forgive me, I'm still at a loss. When I
    > cut and paste your first solution (from a bash command line and from a
    > /bin/sh shell script) I get: ./test-script: 3: Syntax error: Bad
    > substitution.
    >
    > For the second suggestion, I do not have csplit on my FreeBSD box. I do
    > have split and a -p option for a pattern. I tried various combination
    > of your suggestion but either got a usage prompt or no output.
    >
    > I would appreciate further insight on you suggestions.



    Sorry, I was trying to exercise some modesty. Okey, you need my
    extensions to Bash shell (see my .sig) for the first solution:
    http://freshmeat.net/projects/bashdiff/
    http://home.eol.ca/~parkw/index.html#bashdiff
    Since it doesn't use any external libraries,
    http://home.eol.ca/~parkw/bashdiff/b....31-i486-1.tgz
    should suffice.

    However, after looking at the problem in more detail, standard glob
    solution is shorter. Try
    a=`< file`
    b=${a##*1/10/2005}
    echo "$b"

    --
    William Park , Toronto, Canada
    ThinFlash: Linux thin-client on USB key (flash) drive
    http://home.eol.ca/~parkw/thinflash.html
    BashDiff: Super Bash shell
    http://freshmeat.net/projects/bashdiff/

  5. Re: Matching Line After Pattern (Pattern Occurs Multiple Times)

    "REW" said:
    >Hello, I have a sorted list that contains dates:
    >
    >1/1/2005
    >1/1/2005
    >1/8/2005
    >1/10/2005
    >1/10/2005
    >1/10/2005
    >1/15/2005
    >1/21/2005
    >1/21/2005
    >
    >
    >I need a one liner that matches the line after the last occurance of
    >the pattern to the end of the file. So in the example if the regex was
    >1\/10\/2005, it would match after the 3rd occurence of 1/10/2005; the
    >output would contain 3 lines starting at 1/15/2005.


    In awk:
    awk -v pat=1/10/2005 '($0 == pat) { doprint=1; next; } (doprint == 1) { print; }'

    .... or, to clean up the above, put the script in an external file
    (named, say, f.awk):
    ($0 == pat) { doprint=1; next; }
    (doprint == 1) { print; }

    and run with
    awk -f f.awk

    This above form also is suitable for explaining what the script does.
    Awk will process the script pattern-action rules sequentially for each
    input line. The left part (here the parenthesised expression) is
    a rule (pattern) which the input must match in order to execute the
    right part (action, in curly braces).

    For the first line in the script, the action is to compare (literally,
    regexes not involved) the input line with value of variable 'pat'. If
    the input line matched the value of 'pat', variable 'doprint' is set
    to 1, and next input line is read (rules later in the awk script are
    ignored). If the input line did not match value of 'pat', awk execution
    will continue on the second script line. Of course, this rule will
    be executed for all the input lines that contain the desired value,
    but it does not matter here, as the only thing this rule does is
    set a variable to a constant value and start processing the next
    input line.

    On the second script line, the pattern is comparision between the
    value of variable 'doprint' and constant '1'. Only if these are equal,
    the action part of this rule is executed -- and the action will
    just print the input line.


    .... and to finish off the trick, create a standalone awk script:
    #! /usr/bin/awk -f
    ($0 == pat) { doprint=1; next; }
    (doprint == 1) { print; }

    and run with
    ../myscript -v pat=1/10/2005


    --
    Wolf a.k.a. Juha Laiho Espoo, Finland
    (GC 3.0) GIT d- s+: a C++ ULSH++++$ P++@ L+++ E- W+$@ N++ !K w !O !M V
    PS(+) PE Y+ PGP(+) t- 5 !X R !tv b+ !DI D G e+ h---- r+++ y++++
    "...cancel my subscription to the resurrection!" (Jim Morrison)

  6. Re: Matching Line After Pattern (Pattern Occurs Multiple Times)

    REW wrote:
    > Hello, I have a sorted list that contains dates:
    >
    > 1/1/2005
    > 1/1/2005
    > 1/8/2005
    > 1/10/2005
    > 1/10/2005
    > 1/10/2005
    > 1/15/2005
    > 1/21/2005
    > 1/21/2005
    >
    >
    > I need a one liner that matches the line after the last occurance of
    > the pattern to the end of the file. So in the example if the regex was
    > 1\/10\/2005, it would match after the 3rd occurence of 1/10/2005; the
    > output would contain 3 lines starting at 1/15/2005.

    [...]

    awk '$0 == "1/10/2005" { i = 0 ; next }
    { a[++i] = $0 }
    END { for (n = 1; n <= i; n++) print a[n] }' yourfile

+ Reply to Thread