代码之家  ›  专栏  ›  技术社区  ›  Michael Gruenstaeudl

Bash-字符串由未知长度但相同字符组成时的多字符字符串替换

  •  0
  • Michael Gruenstaeudl  · 技术社区  · 3 年前

    假设一个多行文本字符串,其中一些行以一个关键字符开头(在本例中为“#”)。进一步假设您希望将目标字符的所有实例(在本例中为“o”)替换为不同的字符(在本例中为“o”),如果且仅当该目标字符作为两个或多个相邻副本的字符串出现(例如,“ooo”)。在所有不以关键字符开头且必须区分大小写的行中进行替换。

    例如,下面几行。。。

    #Foo bar
    Foo bar
    #Baz foo
    Baz foo
    

    应该转化为:

    #Foo bar
    FOO bar
    #Baz foo
    Baz fOO
    

    以下尝试使用 sed 未保留正确数量的目标字符:

    $ echo -e "#Foo bar\nFoo bar\n#Baz foo\nBaz foo" | sed '/^#/!s/o\{2,\}/O/g'
    #Foo bar
    FO bar
    #Baz foo
    Baz fO
    

    什么代码 塞德 (或其他)是否能正确进行所需的更换?

    2 回复  |  直到 3 年前
        1
  •  0
  •   Wiktor Stribiżew    3 年前

    您可以使用Perl:

    echo -e "#Foo bar\nFoo bar\n#Baz foo\nBaz foo" | perl -pe 's/o{2,}/"O" x length($&)/ge' 
    

    在这里 o{2,} 匹配两个或更多 o 查斯,还有 "O" x length($&) 将这些匹配项替换为 O 这会重复匹配大小的次数( $& 是匹配值)。注意 e 旗手 g 用于计算右侧字符串的值。

    看到了吗 online demo :

    #!/bin/bash
    s="#Foo bar
    Foo bar
    #Baz foo
    Baz foo"
    perl -pe 's/o{2,}/"O" x length($&)/ge' <<< "$s"
    

    输出:

    #FOO bar
    FOO bar
    #Baz fOO
    Baz fOO
    
        2
  •  0
  •   sseLtaH    3 年前

    使用 sed

    $ echo -e "#Foo bar\nFoo bar\n#Baz foo\nBaz foo" | sed '/#/!s/o\+/\U&/'
    #Foo bar
    FOO bar
    #Baz foo
    Baz fOO