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 ...
- 02-10-2009 #1Just 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
The above (obviously) won't work because they're not on the same line.Code:grep 'pattern1.*pattern2' file
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 optionHow would I use this to get rid of lines? Or does anyone have another way how to accomplish this?Code:grep -v '^$' file
- 02-10-2009 #2Linux 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 workthe sun is new every day (heraclitus)
- 02-11-2009 #3Linux Engineer
- Join Date
- Apr 2006
- Location
- Saint Paul, MN, USA / CentOS, Debian, Solaris, SuSE
- Posts
- 1,117
Hi.
This quickly-written demonstration perl script, "p1":
Will look for string Halifax on lines, but only in sections of lines which begin with string alpha and end with string omega.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);
Some environment information, the data file "data1" and results of running the script as
are:Code:./p1 data1
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, drlCode: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 )
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 )
- 02-11-2009 #4Linux 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
- 02-11-2009 #5Just Joined!
- Join Date
- Jan 2009
- Location
- Halifax, NS
- Posts
- 19
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?
- 02-11-2009 #6Linux User
- Join Date
- May 2008
- Location
- NYC, moved from KS & MO
- Posts
- 251
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.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?
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
- 02-12-2009 #7Linux Engineer
- 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):
Producing: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
The cgrep code is not standard, but I had no trouble obtaining and installing it -- it is available at the site noted.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
If you need something yet different from this, then I will await your post of a specific example of data and expected results ... cheers, drlWelcome - 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 )
- 02-12-2009 #8Just Joined!
- Join Date
- Jan 2009
- Location
- Halifax, NS
- Posts
- 19
- 02-12-2009 #9Linux Engineer
- 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:
now if one stops before the install, one can copy the binary -- the executable file -- to wherever one has permission ... cheers, drlCode:< download: ftp, wget, etc > ./configure make make install
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 )
- 02-12-2009 #10Just Joined!
- Join Date
- Jan 2009
- Location
- Halifax, NS
- Posts
- 19
I get stuck at the make install step.
This is the error that I get:
I don't have much experience with tarballs. This is my first time installing one.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'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.


Reply With Quote
