From: WH on
Hi,

I would like to replace beginning 'a's with 'b's in a text file. For
example:

Input

aaaabaaaa
bbaaa

Output

ccccbaaaa
bbaaa

I searched and found that perl has a very simple solution:

perl -pe 's/(^|\G)a/c/g'

The perl regex uses the special \G anchor to mark the position of the
next character. I could not find similar anchor in sed, or vim. Is
there any alternative solution for sed and vim?

Thanks all,
-WH
From: Ed Morton on
On 4/23/2010 6:28 AM, WH wrote:
> Hi,
>
> I would like to replace beginning 'a's with 'b's in a text file. For
> example:
>
> Input
>
> aaaabaaaa
> bbaaa
>
> Output
>
> ccccbaaaa
> bbaaa
>
> I searched and found that perl has a very simple solution:
>
> perl -pe 's/(^|\G)a/c/g'
>
> The perl regex uses the special \G anchor to mark the position of the
> next character. I could not find similar anchor in sed, or vim. Is there
> any alternative solution for sed and vim?

Not that I'm aware of. In awk you'd have to split the string then do the
substitution on the part before the first non-a:

awk '{match($1,/[^a].*/); head=substr($0,1,RSTART-1); gsub(/a/,"c",head); print
head substr($0,RSTART,RLENGTH) }'

Ed.
From: pk on
Ed Morton wrote:

> On 4/23/2010 6:28 AM, WH wrote:
>> Hi,
>>
>> I would like to replace beginning 'a's with 'b's in a text file. For
>> example:
>>
>> Input
>>
>> aaaabaaaa
>> bbaaa
>>
>> Output
>>
>> ccccbaaaa
>> bbaaa
>>
>> I searched and found that perl has a very simple solution:
>>
>> perl -pe 's/(^|\G)a/c/g'
>>
>> The perl regex uses the special \G anchor to mark the position of the
>> next character. I could not find similar anchor in sed, or vim. Is there
>> any alternative solution for sed and vim?
>
> Not that I'm aware of. In awk you'd have to split the string then do the
> substitution on the part before the first non-a:
>
> awk '{match($1,/[^a].*/); head=substr($0,1,RSTART-1); gsub(/a/,"c",head);
> print head substr($0,RSTART,RLENGTH) }'

Well, there are indeed sed solutions, but they're not really pretty.
For example, using a loop and a marker:

s/^/\
/
:loop
s/\na/c\
/
tloop
s/\n//

From: Loki Harfagr on
Fri, 23 Apr 2010 06:59:14 -0500, Ed Morton did cat :

> On 4/23/2010 6:28 AM, WH wrote:
>> Hi,
>>
>> I would like to replace beginning 'a's with 'b's in a text file. For
>> example:
>>
>> Input
>>
>> aaaabaaaa
>> bbaaa
>>
>> Output
>>
>> ccccbaaaa
>> bbaaa
>>
>> I searched and found that perl has a very simple solution:
>>
>> perl -pe 's/(^|\G)a/c/g'
>>
>> The perl regex uses the special \G anchor to mark the position of the
>> next character. I could not find similar anchor in sed, or vim. Is
>> there any alternative solution for sed and vim?
>
> Not that I'm aware of. In awk you'd have to split the string then do the
> substitution on the part before the first non-a:
>
> awk '{match($1,/[^a].*/); head=substr($0,1,RSTART-1);
> gsub(/a/,"c",head); print head substr($0,RSTART,RLENGTH) }'
>
> Ed.

here could be a possible cheat pre-supposing we don't care
much about the real value of the first 'follower' ;D)

$ awk '{gsub(/a/,"c",$1);OFS="b"}1' FS='[^a]' file

Now, it'd lead to a suggestion fot Arnold to see if there's a
possible way to include an 'FT' (for 'FS was here') value just
like there's an 'RT' (for RS was here); which would allow:

$ awk '{gsub(/a/,"c",$1);OFS=FT}1' FS='[^a]' file

From: Ed Morton on
On 4/23/2010 1:05 PM, Loki Harfagr wrote:
> Fri, 23 Apr 2010 06:59:14 -0500, Ed Morton did cat :
>
>> On 4/23/2010 6:28 AM, WH wrote:
>>> Hi,
>>>
>>> I would like to replace beginning 'a's with 'b's in a text file. For
>>> example:
>>>
>>> Input
>>>
>>> aaaabaaaa
>>> bbaaa
>>>
>>> Output
>>>
>>> ccccbaaaa
>>> bbaaa
>>>
>>> I searched and found that perl has a very simple solution:
>>>
>>> perl -pe 's/(^|\G)a/c/g'
>>>
>>> The perl regex uses the special \G anchor to mark the position of the
>>> next character. I could not find similar anchor in sed, or vim. Is
>>> there any alternative solution for sed and vim?
>>
>> Not that I'm aware of. In awk you'd have to split the string then do the
>> substitution on the part before the first non-a:
>>
>> awk '{match($1,/[^a].*/); head=substr($0,1,RSTART-1);
>> gsub(/a/,"c",head); print head substr($0,RSTART,RLENGTH) }'
>>
>> Ed.
>
> here could be a possible cheat pre-supposing we don't care
> much about the real value of the first 'follower' ;D)
>
> $ awk '{gsub(/a/,"c",$1);OFS="b"}1' FS='[^a]' file

Well, if we're going to cheat and get all gawk-specific we could do:

awk -v RS='[^a].*' '{gsub(/a/,"c"); ORS=RT}1' file

:-).

Ed.

>
> Now, it'd lead to a suggestion fot Arnold to see if there's a
> possible way to include an 'FT' (for 'FS was here') value just
> like there's an 'RT' (for RS was here); which would allow:
>
> $ awk '{gsub(/a/,"c",$1);OFS=FT}1' FS='[^a]' file
>