Home > Blockchain >  Replace multiple variations of a string using sed
Replace multiple variations of a string using sed

Time:10-19

I would like to replace variations of a string using sed. The string pattern is required to match a set of optional repeatable characters ("../") and a mandatory string ("foo") For e.g. ../foo ../../foo ../../../foo

I can replace a single version such as ../../../foo using pattern which will yield using sed:

sed - 's/\.\.\/\.\.\/\.\.\/foo/foo1/'

=> foo1 but I want to extend to match any version so I get: ../foo => foo1 ../../foo => foo1 ../../../foo => foo1

How do I achieve this using sed?

CodePudding user response:

You can use

sed -E 's,(\.\./) foo,foo1,' file > newfile

Note the -E option enables the POSIX ERE syntax and the (...) are parsed as a grouping construct and is parsed as a quantifier that matches one or more occurrences of the quantified subpattern.

If you need to make sure the match occurs at the start of the string, add ^ at the beginning: 's,^(\.\./) foo,foo1,'. Note that the comma is used as a regex delimiter here to avoid escaping the / char.

If the foo must be matched as a whole word and if it ends with a word character, add \> closing word boundary construct right after foo.

See the online demo:

s='../foo
../../foo
../../../foo'
sed -E 's,(\.\./) foo,foo1,' <<< "$s"

Output:

foo1
foo1
foo1

CodePudding user response:

With awk you could do it much easier form, just match the pattern and if its found then print the new value.

s='../foo
../../foo
../../../foo'
echo "$s" | awk 'match($0,/(\.\.) \/foo/){print "foo1"}'

Explanation: Simple explanation would be:

  • First creating shell variable named s which has value of foo mentioned by OP in it.
  • Then printing its value by echo command and sending it as a standard input to awk program.
  • In awk program, using awk's match function to match regex (\.\.) \/foo if mentioned regex matched then print new value foo2 in this case.

Explanation of regex:

(\.\.) \/foo: match 2 literal dots(together) with 1 or more occurrences follows by /foo if match found then print the new value.

Output will be as follows:

foo1
foo1
foo1
  • Related