bug-gnu-utils
[Top][All Lists]
Advanced

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

Re: sed bug


From: Bob Proulx
Subject: Re: sed bug
Date: Wed, 18 Mar 2015 14:39:04 -0600
User-agent: Mutt/1.5.23 (2014-03-12)

Jim Meyering wrote:
> Peter Scott wrote:
> > # This works
> > #
> > $ sed 's/foo/bar/i'
> > FOO
> > bar
> > $
> >
> > # I think this should work too.
> > #
> > $ sed '/foo/s//bar/i'
> > sed: -e expression #1, char 13: cannot specify modifiers on empty regexp
> 
> Thanks for spotting and reporting that. I certainly think it should work.
> I suspect it is simply an oversight, and we will fix it for the
> upcoming release.

Why should that work?  The previous regular expression is repeated.
Therefore any case insensitive flags must be attached to the original
expression not the repeat of the original expression.

Isn't that a documented behavior?

     The empty regular expression `//' repeats the last regular
     expression match (the same holds if the empty regular expression is
     passed to the `s' command).  Note that modifiers to regular
     expressions are evaluated when the regular expression is compiled,
     thus it is invalid to specify them together with the empty regular
     expression.

Plus 'i' isn't a traditional sed flag.  It isn't in the legacy Unix
sed.  GNU sed uses 'I' for that purpose, avoiding 'i' already used for
insert.

  `/REGEXP/I'
  `\%REGEXP%I'
     The `I' modifier to regular-expression matching is a GNU extension
     which causes the REGEXP to be matched in a case-insensitive manner.

Therefore the failure makes sense and is documented as such.  The way
to do this action is this following way.  Place the case-insensitive
flag for the regular expression to be matched in the pattern and then
it is applied when it is repeated using the empty expression
shorthand.

  $ echo FOO | sed '/foo/Is//bar/'
  bar

This allows separate control of the address range pattern and the
substitution pattern.

  $ echo FOO | sed '/foo/Is/f/b/I'
  bOO

Unfortunately the 'i' command is already used for inserting lines.
Therefore using 'i' often surprises people by yielding an insertion,
as it should do in retrospect, as a command instead of being a flag.

  $ echo foo | sed '/foo/is/baz/bar/'
  s/baz/bar/

The /foo/ matches and therefore the insert action is triggered.

  `i\'
  `TEXT'
     As a GNU extension, this command accepts two addresses.

     Immediately output the lines of text which follow this command
     (each but the last ending with a `\', which are removed from the
     output).

Since I think that is somewhat confusingly written here is the old sed
doc for that part.  (Where (1) means 1 address max there.)

     (1)i\
     <text> -- insert lines
          The i function  behaves identically to the a function,
          except  that <text> is written to the output before the
          matched line.  All other comments about the a function
          apply to the i function as well.

Bob



reply via email to

[Prev in Thread] Current Thread [Next in Thread]