[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: OT: sed -n vs. sed



William Ballard wrote:
> Bob Proulx wrote:
> >   sed -n '/PATH/p' /etc/profile
> 
> That produces the exact same output as "grep PATH /etc/profile".
> Why not just use grep?

First off let me say that no one is forcing you to use this small
feature of sed.  If you don't understand it then you should not be
using it.  The feature will be waiting there for you when you find the
right application for it.  I don't use every feature of C or C++ in my
programs.  Goodness help me if I tried to do so!  But that does not
mean the feature should be removed.  (Except for the ones I think are
truly Evil. :-)

The return code of sed is only dependent upon whether sed ran.  The
return code of grep is dependent upon whether it matched or not.
Running plain grep in 'sh -e' scripts can cause interactions there.
In 'sh -e' scripts I always use sed as above in that case.  This is
getting really off topic but I have seen people try to protect grep
with 'grep ... || true' when a single sed command would be simpler and
I think less confusing.  Back to the use of -n.

Say that you want to extract the session types from just the KDE X
greeter section of the config file.  It is an ini style file with
section separated by blank lines and withing that section variables.

  sed -n '/^.X-.-Greeter/,/^$/{/SessionTypes=/s///p;}' /etc/kde2/kdm/kdmrc

That prints "default,fvwm2,kde2,failsafe" on my woody system.  It
won't be fooled by SessionTypes which exist in other sections.

Sure I can delete everything from line 1 to the start of the section I
care about.  But that seems more difficult than just using -n which
has the behavior of inverting the effects of searching.

Another example.  Let's say I have a datafile.

  begin a
  a1 stuff
  end a
  begin b
  end b
  c stuff
  begin a
  a2 stuff
  end a
  d stuff
  begin e
  end e

Let's say I want to extract just the 'a' sections.  The following does
it easily.

  sed -n '/begin a/,/end a/p' testdata
  begin a
  a1 stuff
  end a
  begin a
  a2 stuff
  end a

But not using -n is going to be a lot more difficult.  Or maybe not.
Someone will have a clever way of doing it.  But since the -n is so
easy it just makes sense in that case.

> >   sed -n '/^+/q;p' /etc/passwd
> 
> None of the lines in my /etc/passwd start with +, but in in a file thus 
> so I get identical output with "sed '/^+/Q'".

The 'Q' is a new feature of GNU sed.  I recommend avoiding it because
it won't work on many systems.

> I think I can see how -n would be useful once you start using hold 
> space, but at that point I usually just move to perl.

The sed program predates perl by many years.  If you want to use perl
then by all means use perl.  I like perl.  I hate perl.  It is
powerful.  It is different on most of the systems that I need to work
on.  It is not covered by any standard.  Perl updates always break way
too much stuff.

Let's say I am bootstrapping a system such as HP-UX and I want to
install perl on it.  Perl does not exist there until I install it.  I
won't be able to use perl in that case.  But sed is very small, a
standard tool, I can almost always count on sed being there even on
small systems.  And sed will behave exactly as sed has behaved for 30
years.  It is a scalpel not a chainsaw.

Bob

Attachment: pgpcIjFo6qmW3.pgp
Description: PGP signature


Reply to: