This is virtually impossible, due to the way regular expressions work. As jvb already pointed out, a solution is simple (though not necessarily short) if the maximum number of consecutive source characters is known. If not,
it is possible to change all source characters first, and then change back the single characters in a second step. However, this only works if the target character does not occur in the input stream, or if you can use a character known not to occur in the input stream as an intermediate target.
Furthermore, you need to take the corner cases of a single source character occuring a the beginning or the end of the line into account. Thus:
tr ',' '|' < file | sed 's/\([^|]\)|\([^|]\)/\1,\2/;s/^|\([^|]\)/,\1/;s/\([^|]\)|$/\1,/'
or
sed 's/,/|/g;s/\([^|]\)|\([^|]\)/\1,\2/;s/^|\([^|]\)/,\1/;s/\([^|]\)|$/\1,/' file
A solution using a language that has a notion of string length would be more robust.
So you need a global replacement of a character with another one, in a file? – Alex – 2017-06-02T06:16:40.757
Yes, but only where there are 2+ repetitions of it. – xman – 2017-06-02T06:52:39.483
This can be easily achieved with
perl
:perl -lape 's/,{2,}/"|" x length($&)/ge'
. Too bad you can't use it (why?). It can be called from withinvi
, don't know whether that's admissible in your situation. – simlev – 2017-09-19T15:00:13.947