How to use sed command to add a line before a template line?

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

When I search for the template foo, foo is not at the beginning or end of the line, I want to add a panel to foo, how can I do this with 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 
+7
source share
3 answers

You can just use something like:

 sed 's/foo/barfoo/g' baz 

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

For an arbitrary (not fixed) pattern, such as foo[0-9] , you can 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 brackets capture the actual text that matches the pattern, and \1 uses it as a wildcard.

You can use arbitrarily complex patterns with this, including matching only complete words. For example, only a template change if it is 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 capture groups work, you can use parentheses to store text that matches the pattern for later use in replacement. Captured identifiers are based on characters ( reading from left to right, so regex (I left the escape characters \ and added it a bit for clarity):

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

when applied to Pax Diablo text, you get three groups:

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

as below:

 pax$ echo 'Pax Diablo' | sed 's/\(\(\S*\) \(\S*\)\)/[\1] [\2] [\3]/' [Pax Diablo] [Pax] [Diablo] 
+14
source

Just replace the beginning of the line with something else.

 sed '/^foo/s/^/bar/' 
+3
source

To replace or change all "foo" except at the beginning and at the end of the line, I would suggest temporarily replacing them at the beginning and end of the line with a unique breakpoint value.

 sed 's/^foo/____veryunlikelytoken_bol____/ s/foo$/____veryunlikelytoken_eol____/ s/foo/bar&/g s/^____veryunlikelytoken_bol____/foo/ s/____veryunlikelytoken_eol____$/foo/' 

There is no way in sed to indicate "cannot match here." In Perl regular expressions and their derivatives (which means languages โ€‹โ€‹that are borrowed from Perl regular expressions, not necessarily languages โ€‹โ€‹derived from Perl), you have various negative statements, so you can do something like

 perl -pe 's/(?!^)foo(?!$)/barfoo/g' 
0
source

All Articles