Reputation:
I have tried the following command:
echo "123456,,7,,,,890" | sed 's/,,/\,?,/g'
Result:
123456,?,7,?,,?,890
But the result I want is:
123456,?,7,?,?,?,890
Could anyone help me ?
Thanks
Upvotes: 0
Views: 55
Reputation: 26703
Your problem is, that the ,,
in the result was never seen by the g
option.
One of the two is coming from replacing.
With your special desired output (I would have expect only three instead of four replacements...) you need to look at the result of one replacement and replace again, until no replacing takes place anymore.
You can achieve that by making a loop, with :a
, i.e. the label "a" and then go back after a successful replacement with ta
, "to label a".
(The g
becomes unnecessary, but might be more efficient. Time it to find out in your environment.)
sed ':a;s/,,/\,?,/g;ta'
result
"123456,?,7,?,?,?,890"
Upvotes: 2
Reputation: 198388
Regular expressions can not match overlapping spans. Thus, if you have ,,,,
, the first two commas will be the first match, and the third and fourth comma will constitute the second match. There is no way to match the second and third comma with /??/
.
Typically, this would be done using lookahead, to avoid one of the commas to be a part of the match; but sed
does not support it. So you can switch to a more powerful regex engine, like that of perl
:
echo "123456,,7,,,,890" | perl -pe 's/,(?=,)/,?/g'
Alternately, since in your specific case you will miss every other adjacent comma pair, you can just run your sed
twice:
echo "123456,,7,,,,890" | sed 's/,,/,?,/g' | sed 's/,,/,?,/g'
or combine the two operations into one sed
invocation:
echo "123456,,7,,,,890" | sed 's/,,/\,?,/g; s/,,/,?,/g'
Upvotes: 1