Find the answer to your Linux question:
Page 1 of 2 1 2 LastLast
Results 1 to 10 of 15
Hi everyone, grep matches lines, but I'm trying to match a line that itself contains no patterns, but it is within a pattern. Thus for example, pattern1 text that I ...
  1. #1
    Just Joined!
    Join Date
    Jan 2009
    Location
    Halifax, NS
    Posts
    19

    Match a line between patterns

    Hi everyone,

    grep matches lines, but I'm trying to match a line that itself contains no patterns, but it is within a pattern.

    Thus for example,

    pattern1
    text that I want to match
    pattern2

    Code:
    grep 'pattern1.*pattern2' file
    The above (obviously) won't work because they're not on the same line.

    How would I be able to do this with the text not being on the same line as a pattern (using grep if possible)?

    Any help is appreciated. (Did a quick Google and forum search but couldn't find anything.)

    edit: I was thinking of removing all new lines and thus having the text in the file show up as:

    pattern1 text that I want to match pattern2

    and then it would be easy to match the text.
    I know how to get rid of preceding and trailing whitespaces using grep's invert-match option
    Code:
    grep -v '^$' file
    How would I use this to get rid of lines? Or does anyone have another way how to accomplish this?

  2. #2
    tpl
    tpl is offline
    Linux User
    Join Date
    Jan 2007
    Location
    cleveland
    Posts
    452
    try awk: the "range pattern" is setup for what
    you want to do: something like this:

    awk '/pattern2,pattern2/ {delete}' <filename

    might need some tweaking to get the delete to work
    the sun is new every day (heraclitus)

  3. #3
    drl
    drl is offline
    Linux Engineer drl's Avatar
    Join Date
    Apr 2006
    Location
    Saint Paul, MN, USA / CentOS, Debian, Solaris, SuSE
    Posts
    1,117
    Hi.

    This quickly-written demonstration perl script, "p1":
    Code:
    #!/usr/bin/perl
    
    # @(#) p1       Demonstrate bracketed search.
    
    use warnings;
    use strict;
    
    my ($debug);
    $debug = 0;
    $debug = 1;
    
    my ($op) = "alpha";
    my ($cp) = "omega";
    my ($p)  = "Halifax";
    
    my ($looking_for_opening) = 1;
    my ($hits)                = 0;
    my (@lines);
    my ($sections) = 0;
    
    while (<>) {
      if ($looking_for_opening) {    # skip everything until opening
        if (/$op/) {
          $looking_for_opening = 0;
          @lines               = ();
          push @lines, $_;
        }
      }
      else {    # after opening, look for closing, or main match
        if (/$cp/) {
          if ( $hits > 0 ) {
            push @lines, $_;
            print @lines;
          }
          @lines               = ();
          $looking_for_opening = 1;
          $sections++;
          print " (debug): found $hits hits in section $sections\n" if $debug;
          $hits = 0;
          next;
        }
        elsif (/$p/) {
          $hits++;
        }
        push @lines, $_;
      }
    }
    
    print STDERR " ( Lines read: $. )\n";
    
    exit(0);
    Will look for string Halifax on lines, but only in sections of lines which begin with string alpha and end with string omega.

    Some environment information, the data file "data1" and results of running the script as
    Code:
    ./p1 data1
    are:
    Code:
    Environment: LC_ALL = C, LANG = C
    (Versions displayed with local utility "version")
    OS, ker|rel, machine: Linux, 2.6.11-x1, i686
    Distribution        : Xandros Desktop 3.0.3 Business
    GNU bash 2.05b.0
    perl 5.8.4
    
     Data file data1:
    # Wed Feb 11 04:42:41 CST 2009
    # Data file for bracketed match.
    
    alpha
    Text1
    Text2
    This is a line to be matched "Halifax"
    Text3
    omega
    
    beta
    alpha
    Text4
    but there is no match in this bracket section.
    Text5
    omega
    
    # End of data file for bracketed match.
    
     Results:
    alpha
    Text1
    Text2
    This is a line to be matched "Halifax"
    Text3
    omega
     (debug): found 1 hits in section 1
     (debug): found 0 hits in section 2
     ( Lines read: 18 )
    Other additions, such as easily changeable patterns, printing options of sections (e.g. only the main matching lines), etc., are left as an exercise ... cheers, drl
    Welcome - get the most out of the forum by reading forum basics and guidelines: click here.
    90% of questions can be answered by using man pages, Quick Search, Advanced Search, Google search, Wikipedia.
    We look forward to helping you with the challenge of the other 10%.
    ( Mn, 2.6.n, AMD-64 3000+, ASUS A8V Deluxe, 1 GB, SATA + IDE, Matrox G400 AGP )

  4. #4
    Linux User
    Join Date
    May 2008
    Location
    NYC, moved from KS & MO
    Posts
    251
    You can try sed:
    1. create a text file a.sed:
    /pattern1/{
    N
    N
    s/pattern1\n.*\npattern2/something else/
    }

    2. sed -f a.sed file
    now the pattern lines are replaced with "something else"

    OR

    change a.sed to
    /pattern1/{
    N
    N
    /pattern1\n.*\npattern2/d
    }

    then
    sed -f a.sed file
    to delete the pattern lines

  5. #5
    Just Joined!
    Join Date
    Jan 2009
    Location
    Halifax, NS
    Posts
    19
    Quote Originally Posted by secondmouse View Post
    You can try sed:
    1. create a text file a.sed:
    /pattern1/{
    N
    N
    s/pattern1\n.*\npattern2/something else/
    }

    2. sed -f a.sed file
    now the pattern lines are replaced with "something else"

    OR

    change a.sed to
    /pattern1/{
    N
    N
    /pattern1\n.*\npattern2/d
    }

    then
    sed -f a.sed file
    to delete the pattern lines
    Thanks for the reply secondmouse,

    I was actually looking at sed for doing this before I saw your reply. After all, sed has the ability to look at multiple lines in the pattern space, which allows you to match patterns which extend over multiple lines.

    The thing is I've never used sed for such a task before, and all the examples I could find have all created a sed file.

    I'd like to do this on command line if possible (not by creating a file); how would the syntax look like? I tried some stuff but kept getting errors.

    edit: In my first post I asked if this was possible to do with grep. I don't believe it is, but can anyone confirm this?

  6. #6
    Linux User
    Join Date
    May 2008
    Location
    NYC, moved from KS & MO
    Posts
    251
    edit: In my first post I asked if this was possible to do with grep. I don't believe it is, but can anyone confirm this?
    It's true grep is not up for this kind of task, see [ [Chapter 27] 27.11 A Multiline Context grep Using sed ], first paragraph. Maybe agrep (which is not under GPL) can do that but I haven't tried.

    For deleting with sed one-liner:
    sed -e '/pattern1/,/pattern2/d' file

    For replacing,
    sed '/^pattern1$/{N;N;/.*pattern2$/s/.*/somethingelse/;}' file

    The replacement solution I got it from:
    how to replace multiple lines in a file? - comp.unix | Google Groups

  7. #7
    drl
    drl is offline
    Linux Engineer drl's Avatar
    Join Date
    Apr 2006
    Location
    Saint Paul, MN, USA / CentOS, Debian, Solaris, SuSE
    Posts
    1,117
    Hi.

    I thought you wanted a 3-pattern windowed match. If an open-close sequence is desired, cgrep can do that (and much more):
    Code:
    #!/usr/bin/env bash
    
    # @(#) s2       Demonstrate patterned window feature of cgrep.
    # http://www.bell-labs.com/project/wwexptools/cgrep/
    
    echo
    set +o nounset
    LC_ALL=C ; LANG=C ; export LC_ALL LANG
    echo "Environment: LC_ALL = $LC_ALL, LANG = $LANG"
    echo "(Versions displayed with local utility \"version\")"
    version >/dev/null 2>&1 && version "=o" $(_eat $0 $1) cgrep
    set -o nounset
    echo
    
    FILE=${1-data3}
    
    echo " Data file $FILE:"
    cat $FILE
    
    echo
    echo " Results:"
    cgrep +w "omega" "alpha" $FILE
    
    exit 0
    Producing:
    Code:
    % ./s2
    
    Environment: LC_ALL = C, LANG = C
    (Versions displayed with local utility "version")
    OS, ker|rel, machine: Linux, 2.6.11-x1, i686
    Distribution        : Xandros Desktop 3.0.3 Business
    GNU bash 2.05b.0
    cgrep - (local: ~/executable/cgrep Sep 28 2007 )
    
     Data file data3:
    Thu Feb 12 04:22:38 CST 2009
    # Data file for open-close sequence extraction.
    
    alpha
    Text1
    omega
    
    # Extraneous data
    # is not within an opening - closing sequence.
    
    Dalhousie is in Halifax.
    
    beta
    alpha
    Text2
    Text3
    omega
    
    # Only the window boundaries, no enclosed text.
    
    alpha
    omega
    
    # End of data file for bracketed match.
    
     Results:
    ========================================
    alpha
    Text1
    omega
    ========================================
    alpha
    Text2
    Text3
    omega
    ========================================
    alpha
    omega
    The cgrep code is not standard, but I had no trouble obtaining and installing it -- it is available at the site noted.

    If you need something yet different from this, then I will await your post of a specific example of data and expected results ... cheers, drl
    Welcome - get the most out of the forum by reading forum basics and guidelines: click here.
    90% of questions can be answered by using man pages, Quick Search, Advanced Search, Google search, Wikipedia.
    We look forward to helping you with the challenge of the other 10%.
    ( Mn, 2.6.n, AMD-64 3000+, ASUS A8V Deluxe, 1 GB, SATA + IDE, Matrox G400 AGP )

  8. #8
    Just Joined!
    Join Date
    Jan 2009
    Location
    Halifax, NS
    Posts
    19
    Quote Originally Posted by drl View Post
    Hi.

    I thought you wanted a 3-pattern windowed match. If an open-close sequence is desired, cgrep can do that (and much more):

    The cgrep code is not standard, but I had no trouble obtaining and installing it -- it is available at the site noted.

    If you need something yet different from this, then I will await your post of a specific example of data and expected results ... cheers, drl
    Thanks drl. I tried installing cgrep but the installation failed for me because I do not have root access on this machine.

    I'll continue using sed. Thank you secondmouse.

  9. #9
    drl
    drl is offline
    Linux Engineer drl's Avatar
    Join Date
    Apr 2006
    Location
    Saint Paul, MN, USA / CentOS, Debian, Solaris, SuSE
    Posts
    1,117
    Hi.

    I installed it in a directory in HOME that I call executable, and that directory is made to be part of my PATH environment variable.

    I don't recall the details for creating cgrep, but the usual sequence is:
    Code:
    < download: ftp, wget, etc >
    ./configure
    make
    make install
    now if one stops before the install, one can copy the binary -- the executable file -- to wherever one has permission ... cheers, drl
    Welcome - get the most out of the forum by reading forum basics and guidelines: click here.
    90% of questions can be answered by using man pages, Quick Search, Advanced Search, Google search, Wikipedia.
    We look forward to helping you with the challenge of the other 10%.
    ( Mn, 2.6.n, AMD-64 3000+, ASUS A8V Deluxe, 1 GB, SATA + IDE, Matrox G400 AGP )

  10. #10
    Just Joined!
    Join Date
    Jan 2009
    Location
    Halifax, NS
    Posts
    19
    Quote Originally Posted by drl View Post
    Hi.

    I installed it in a directory in HOME that I call executable, and that directory is made to be part of my PATH environment variable.

    I don't recall the details for creating cgrep, but the usual sequence is:
    Code:
    < download: ftp, wget, etc >
    ./configure
    make
    make install
    now if one stops before the install, one can copy the binary -- the executable file -- to wherever one has permission ... cheers, drl
    I get stuck at the make install step.
    This is the error that I get:
    Code:
    make[1]: Entering directory `/home/dennis/cgrepsrc/cgrep-8.15'
    /bin/sh ./mkinstalldirs /usr/bin
      /usr/bin/install -c cgrep /usr/bin/cgrep
    /usr/bin/install: cannot create regular file `/usr/bin/cgrep': Permission denied
    make[1]: *** [install-binPROGRAMS] Error 1
    make[1]: Leaving directory `/home/dennis/cgrepsrc/cgrep-8.15'
    make: *** [install-am] Error 2
    I don't have much experience with tarballs. This is my first time installing one.

    I'd rather use cgrep than sed, because cgrep is more suitable for the task. Thanks for helping me out.

    edit: Nevermind, I found my way around it.

Page 1 of 2 1 2 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...