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
swhich has value of foo mentioned by OP in it. - Then printing its value by
echocommand and sending it as a standard input toawkprogram. - In
awkprogram, usingawk'smatchfunction to match regex(\.\.) \/fooif mentioned regex matched then print new valuefoo2in 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
