Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use sed command to add a string before a pattern string?

Tags:

bash

sed

I want to use sed to modify my file named "baz".

When i search a pattern foo , foo is not at the beginning or end of line, i want to append bar before foo, how can i do it using sed?

Input file named baz:
blah_foo_blahblahblah
blah_foo_blahblahblah
blah_foo_blahblahblah
blah_foo_blahblahblah

Output file 
blah_barfoo_blahblahblah
blah_barfoo_blahblahblah
blah_barfoo_blahblahblah
blah_barfoo_blahblahblah
like image 241
TheOneTeam Avatar asked Jul 08 '11 04:07

TheOneTeam


People also ask

How do you insert a sed line after a pattern?

You have to use the “-i” option with the “sed” command to insert the new line permanently in the file if the matching pattern exists in the file.

How do you insert a first line using sed?

Use sed 's insert ( i ) option which will insert the text in the preceding line.


2 Answers

You can just use something like:

sed 's/foo/barfoo/g' baz

(the g at the end means global, every occurrence on each line rather than just the first).

For an arbitrary (rather than fixed) pattern such as foo[0-9], you could use capture groups as follows:

pax$ echo 'xyz fooA abc
xyz foo5 abc
xyz fooB abc' | sed 's/\(foo[0-9]\)/bar\1/g'

xyz fooA abc
xyz barfoo5 abc
xyz fooB abc

The parentheses capture the actual text that matched the pattern and the \1 uses it in the substitution.

You can use arbitrarily complex patterns with this one, including ensuring you match only complete words. For example, only changing the pattern if it's immediately surrounded by a word boundary:

pax$ echo 'xyz fooA abc
xyz foo5 abc foo77 qqq xfoo4 zzz
xyz fooB abc' | sed 's/\(\bfoo[0-9]\b\)/bar\1/g'

xyz fooA abc
xyz barfoo5 abc foo77 qqq xfoo4 zzz
xyz fooB abc

In terms of how the capture groups work, you can use parentheses to store the text that matches a pattern for later use in the replacement. The captured identifiers are based on the ( characters reading from left to right, so the regex (I've left off the \ escape characters and padded it a bit for clarity):

( ( \S* )   ( \S* ) )
^ ^     ^   ^     ^ ^
| |     |   |     | |
| +--2--+   +--3--+ |
+---------1---------+

when applied to the text Pax Diablo would give you three groups:

\1 = Pax Diablo
\2 = Pax
\3 = Diablo

as shown below:

pax$ echo 'Pax Diablo' | sed 's/\(\(\S*\) \(\S*\)\)/[\1] [\2] [\3]/'
[Pax Diablo] [Pax] [Diablo]
like image 66
paxdiablo Avatar answered Oct 23 '22 12:10

paxdiablo


Just substitute the start of the line with something different.

sed '/^foo/s/^/bar/'
like image 45
Ignacio Vazquez-Abrams Avatar answered Oct 23 '22 13:10

Ignacio Vazquez-Abrams