From: Wayne on
sharma__r(a)hotmail.com wrote:
> On Oct 7, 8:27 am, Ed Morton <mortons...(a)gmail.com> wrote:
> ...
> This will work:
>
> sed -e '
> /pattern1/!d
> n
> /pattern2/!d
> ' yourfile
>
>
> -- Rakesh

Actually this doesn't work. Consider this file:

pattern1 line 1
pattern1 line 2
pattern2 line 3

This sed program only displays line 1. The
awk solution correctly displays all three lines.

I think this will work, not sure if it's the simplest
sed solution though:

sed -ne '
: top
/pattern1/ {
p
n
/pattern2/p
/pattern1/b top
}
' "$1"

--
Wayne
From: sharma__r on
On Oct 7, 10:57 pm, Wayne <nos...(a)all.4me.invalid> wrote:
> sharma...(a)hotmail.com wrote:
> > On Oct 7, 8:27 am, Ed Morton <mortons...(a)gmail.com> wrote:
> > ...
> > This will work:
>
> > sed -e '
> >    /pattern1/!d
> >    n
> >    /pattern2/!d
> > ' yourfile
>
> > -- Rakesh
>
> Actually this doesn't work.  Consider this file:
>
> pattern1 line 1
> pattern1 line 2
> pattern2 line 3
>
> This sed program only displays line 1.  The
> awk solution correctly displays all three lines.
>
> I think this will work, not sure if it's the simplest
> sed solution though:
>
> sed -ne '
> : top
> /pattern1/ {
>   p
>   n
>   /pattern2/p
>   /pattern1/b top}
>
> ' "$1"
>
> --
> Wayne


Thanks for pointing that out. Actually it just needs a minor change:

sed -e '
:top
/pattern1/!d
n
/pattern2/b
btop
' yourfile

-- Rakesh
From: Ed Morton on
On Oct 7, 1:57 pm, sharma...(a)hotmail.com wrote:
<snip>
> Thanks for pointing that out. Actually it just needs a minor change:
>
> sed -e '
>      :top
>      /pattern1/!d
>      n
>      /pattern2/b
>      btop
> ' yourfile
>
> -- Rakesh- Hide quoted text -

Just curious, if you don't mind indulging me: how would you enhance
that script if your requirements changed slightly to, say, print the
line numbers before the lines, i.e. the equivalent of changing this:

awk '/Ultra/ {print; found=1; next}
found && /fixed/ {print}
{found=0}' file

to this:

awk '/Ultra/ {print NR,$0; found=1; next}
found && /fixed/ {print NR,$0}
{found=0}' file

or if you wanted to only print the second line if it was longer than
10 characters:

awk '/Ultra/ {print; found=1; next}
found && /fixed/ && (length>10) {print}
{found=0}' file

or if you wanted to, at the end of running the script, print a count
of all the lines that matched each pattern:

awk '/Ultra/ {print; found=1; count1++; next}
found && /fixed/ {print; count2++}
{found=0}
END{print count1+0, count2+0}' file

Regards,

Ed.

From: Michael Paoli on
On Oct 6, 4:17 pm, Jack Shown <jackshown(a)gmail.com> wrote:
> Is it possible using sed, awk, perl or anything else to search a file
> for a regex and if that line is followed by another regex then display
> both lines otherwise display only the first line?

Yes.

Oh, ... maybe you want an example? How about:

sed -ne '
/re1/{
p
:2
n
/re2/!b2
p
q
}
'

> For example, suppose I grep a file for "Ultra" but want the following
> line also output if the following line contains "fixed".

That latter specification conflicts with the former ("line is followed
by another regex" and "the following line contains" are in general not
the same), and isn't sufficient to unambiguously stand on its own - so
not sure what's desired there.

Perhaps the latter is intended to be like the former, except only
considers the 2nd regex on the line immediately after the first regex,
e.g.:
sed -ne '
/re1/{
p
n
/re2/p
q
}
'
From: sharma__r on
On Oct 8, 12:28 am, Ed Morton <mortons...(a)gmail.com> wrote:
> On Oct 7, 1:57 pm, sharma...(a)hotmail.com wrote:
> <snip>
>
> > Thanks for pointing that out. Actually it just needs a minor change:
>
> > sed -e '
> >      :top
> >      /pattern1/!d
> >      n
> >      /pattern2/b
> >      btop
> > ' yourfile
>
> > -- Rakesh- Hide quoted text -
>
> Just curious, if you don't mind indulging me: how would you enhance
> that script if your requirements changed slightly to, say, print the
> line numbers before the lines, i.e. the equivalent of changing this:
>
> awk '/Ultra/ {print; found=1; next}
>         found && /fixed/ {print}
>         {found=0}' file
>
> to this:
>
> awk '/Ultra/ {print NR,$0; found=1; next}
>         found && /fixed/ {print NR,$0}
>         {found=0}' file
>
> or if you wanted to only print the second line if it was longer than
> 10 characters:
>
> awk '/Ultra/ {print; found=1; next}
>         found && /fixed/ && (length>10) {print}
>         {found=0}' file
>
> or if you wanted to, at the end of running the script, print a count
> of all the lines that matched each pattern:
>
> awk '/Ultra/ {print; found=1; count1++; next}
>         found && /fixed/ {print; count2++}
>         {found=0}
>         END{print count1+0, count2+0}' file
>
> Regards,
>
>     Ed.


You could try this on a bourne-shell based command line:

## to print the line numbers alongwith the lines
sed -e '
:a
/RE1/!d
=;n
/RE2/!ba
=
' yourfile


## to print the second line only if it's length were more than 10
characters.
sed -e '
:a
/RE1/!d
n
/RE2/!ba
/.\{10\}/!d
' yourfile


-- Rakesh
First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4
Prev: A couple of sed questions
Next: How to ls -lh on a FreeBSD?