Re: sed bug
Jim Meyering <[email protected]> Wed, 18 Mar 2015 14:31:45 -0700
| Newsgroups | gmane.comp.gnu.utils.bugs |
|---|---|
| Message-ID | <CA+8g5KG1MJef=asHvb0BSq3sVuip94Dqug68ivH5iSeyxzT65w@mail.gmail.com> |
tags 20138 notabug thanks On Wed, Mar 18, 2015 at 1:39 PM, Bob Proulx <[email protected]> wrote: > 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. Well, that will teach me to reply before looking at code/documentation. Thanks, Bob! It is clearly not a bug after all.