Regex Sed将一个字符的多次重复替换为另一个字符的多次重复

Regex Sed将一个字符的多次重复替换为另一个字符的多次重复,regex,sed,substitution,Regex,Sed,Substitution,如果我有一篇像这样的文字,但是主角的重复次数可以改变 aaaabbaaccc 我想将文本开头的a替换为xgiving xxxxbbbbaaccc 我想用正则表达式和sed,而不是tr或awk来实现这一点 您只需执行以下操作: echo 'aaaabbbbaaaacccc' | sed 's/^aaaa/xxxx/' 您可以使用循环: echo aaaabbbbaaaacccc | sed ':l s/^\(x*\)a/\1x/;tl' 一个答案在于使用sed的条件分支机制,我认为: sed

如果我有一篇像这样的文字,但是主角的重复次数可以改变

aaaabbaaccc

我想将文本开头的
a
替换为
x
giving

xxxxbbbbaaccc


我想用正则表达式和
sed
而不是
tr
awk
来实现这一点

您只需执行以下操作:

echo 'aaaabbbbaaaacccc' | sed 's/^aaaa/xxxx/'
您可以使用循环:

echo aaaabbbbaaaacccc | sed ':l s/^\(x*\)a/\1x/;tl'

一个答案在于使用sed的条件分支机制,我认为:

sed ':b; s/^\(x*\)a/\1x/; t b'
它用一组原始的
x
,以及另一组
x
,替换一个多个
x
的零序加上一个
a
:b
创建标签
b
;如果自上次检查
sed
以来执行了替换,则
tb
跳到标签
b

唯一一次遇到麻烦的是如果你有一行像
aaaaxaab
;它跳过第一个
x
,在不应该的时候优先翻译后续的
a

在Mac OS X上测试时,我不得不将其修改为:

sed -e ':b' -e 's/^\(x*\)a/\1x/' -e 't b' <<< aaaaaxaaab
sed-e':b'-e's/^\(x*\)a/\1x/'-e'tb'Perl也:

$ perl -pe 's/^a+/ "hello" x length($&) /e'  <<< aaaabbbbaaaacccc
hellohellohellohellobbbbaaaacccc

$perl-pe's/^a+/“hello”x长度($&)/e'这里有一些东西至少可以在一行输入上工作

我不得不做一些奇怪的事情来得到评论

echo '{
        h                 ;# copy the line
        s/^(a+)(.*)/\1/   ;# get just the leading aa  aaaa
        y/a/x/            ;# change aa to xx
        x                 ;# swap the xx and the line
        s/^(a+)(.*)/\2/   ;# remove the leading aa from the line  bbbbaaaacccc
        x                 ;# swap bbbbaaaacccc for xxxx
        G                 ;# append bbbbaaaacccc
        s/\n//            ;# get rid of the intervening new line
}' > s2.sed ; echo aaaabbbbaaaacccc | sed -rf s2.sed     

xxxxbbbbaaaacccc


echo '{
        h                 ;# copy the line
        s/^(a+)(.*)/\1/   ;# get just the leading aa  aaaa
        s/a/hello/g       ;# or change stuff to hello...
        x                 ;# swap the xx and the line
        s/^(a+)(.*)/\2/   ;# remove the leading aa from the line  bbbbaaaacccc
        x                 ;# swap bbbbaaaacccc for xxxx
        G                 ;# append bbbbaaaacccc
        s/\n//            ;# get rid of the intervening new line
}' > s3.sed ; echo aaaabbbb| sed -rf s3.sed     

hellohellohellohellobbbb
这可能适用于您(GNU-sed):

在第一个非a之前放置一个标记。将该行复制到保留空间。更改图案空间中的线条。附加原始行。移除不需要的部分

要将
a
更改为
hello

sed 's/a*/&\n/;h;s/a/hello/g;G;s/\n.*\n//' file

应该说,我事先不知道行首有多少个“a”,如果我想用多个字符替换每个出现的“a”,例如aaaabbb变成hellohellohellohellobbbb
sed:l s/^\(\(hello\)*)a/\1hello/;tl'
谢谢你的解释+1:很好。您可以使用多行引号字符串作为sed的参数来避免临时文件。如果使用临时文件,也应该删除临时文件(最好使用
陷阱
,因此如果用户中断,临时文件仍然会被删除)。我实际上希望保存脚本。它是这样发布的,所以你可以将它c&p到一个shell中。
sed 's/a*/&\n/;h;s/a/hello/g;G;s/\n.*\n//' file