Reputation: 21
I need to modify a script, and I need to add a line before the first match of a "begin" statement with the string "some text" on its own line. The following command does the job, but I cannot figure out how to make it case insensitive:
sed -i '0,/begin/s//some text\nbegin/' filename
This fails:
sed -i '0,/begin/s//some text\nbegin/i' filename
...with the error sed: -e expression #1, char 45: cannot specify modifiers on empty regexp
How can I make this replacement case insensitive?
Upvotes: 2
Views: 153
Reputation: 52132
You're using an address range including line 0, so I guess you're using GNU sed. In that case, there is an extension to the regex used in the address, namely an I
modifier:
$ printf 'Text\nBegin\n' |sed '0,/begin/I s//some text\nbegin/'
Text
some text
begin
This matches case insensitively, but still always inserts a lowercase "begin". To avoid changing it, you can use
$ printf 'Text\nBegin\n' | sed '/begin/I i some text'
/begin/I
matches case insensitively, i
inserts the text following it on a separate line before the matching line.
To make sure this only modifies the first instance as in your example, you can combine it with an address range again:
printf 'Text\nBegin\n' | sed '0,/begin/I{/begin/I i some text
}'
Sed gets a little finicky with i
and line breaks combined with braces, so inserting an actual linebreak seems to be required. The classical way is to have the argument to the i
command on a completely separate line:
sed '0,/begin/I{
/begin/I i\
some text
}'
Or, briefer (hat tip to Etan Reisner):
sed '0,/.*begin/I s//some text\n&/'
This captures everything on the line containing begin
and inserts "some text" with a newline before the matched string, preserving whatever might be on that line already.
Upvotes: 1