Execution cycle of sed s/REGEXP/REPLACEMENT/g
Because with the two ,
s in (,\)\(,\)
, you have already matched the first two ,
s and the Regex pattern matched so far won't backtrack for the rest of the line. Only one is left now that is the last ,
hence it just printed as it is without any *
in between it the second last one.
If you have another ,
in input, you would get the desired (global, g
) response:
% echo ,,,, | sed s':\(,\)\(,\):\1*\2:'g
,*,,*,
The why of the question been already answered by @heemayl
Workaround with sed
(here assuming GNU sed
) - loop recursively as long as a match is found
$ echo ,,, | sed -E ':a s/(,)(,)/\1*\2/ ; ta'
,*,*,
$ echo ,,,, | sed -E ':a s/(,)(,)/\1*\2/ ; ta'
,*,*,*,
POSIXly:
$ echo ,,,, | sed -e :a -e 's/\(,\)\(,\)/\1*\2/; ta'
,*,*,*,
Or with perl
$ echo ,,, | perl -pe 's/,\K(?=,)/*/g'
,*,*,
$ echo ,,,, | perl -pe 's/,\K(?=,)/*/g'
,*,*,*,