user7862197
user7862197

Reputation:

how to replace each ,, with ,?, using sed?

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

Answers (2)

Yunnosch
Yunnosch

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

Amadan
Amadan

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

Related Questions