0

Match everything between comment: the next ; or end of line and replace it with the word bar

s="/home/user/14.JPG;comment:foo;sometag;sort:30"
sed "s/comment:(\w+)/\bar/g" <<< $s

Returns

/home/user/14.JPG;comment:foo;sometag;sort:30

Instead of

/home/user/14.JPG;comment:bar;sometag;sort:30

What am I doing wrong?

jjk
  • 411

2 Answers2

2

First, you are trying to use extended regular expressions (ERE) but Sed uses basic regular expressions (BRE) by default. Namely, () for grouping and + for "one or more" is ERE. For more details, read why does my regular expression work in X but not in Y?. To activate ERE, use the -E flag (but we will not need it for the solution).

Even that would not be enough, because you are also matching comment:(\w+), but

  • You don't re-introduce comment:. Put it in the substitution slot.
  • Being \w a GNU extension to match word characters, (\w+) is not "everything up to the next ;" as the question claims, that would be [^;]*.

The solution is

sed 's/comment:[^;]*/comment:bar/g'
Quasímodo
  • 18,865
  • 4
  • 36
  • 73
-1

you can use the group and called by numbing, for replace yyy by xxx by grouping :

$ echo "foo yyy bar" | sed 's/\(foo\).*\( bar\)/\1 xxx \2/'  
foo xxx bar

in your case :

sed "s/\(comment:\).*\(sometag\)/\1bar\2/g" <<< $s
nextloop
  • 166
  • 1
    Hi Ayoub, thanks for your contribution, but it would be better if it directly addressed the example in the question instead of using another one, as it may not be entirely clear how one adapts this to solve the issue. – Quasímodo Mar 22 '21 at 11:21
  • yes you can use sed as you well, but for me ,using group give me a powerfull to do anything – nextloop Mar 22 '21 at 12:15
  • (fool)=\1 , (bar)=2, so , you can use it as variable as you well – nextloop Mar 22 '21 at 12:17
  • griup allow something like : (.*comment:) and called by \1 ,it's easy and powerfull – nextloop Mar 22 '21 at 12:19