代码之家  ›  专栏  ›  技术社区  ›  SwiftyCocoa

SED仅替换第一次出现的图案,即使带有“g”标志

  •  0
  • SwiftyCocoa  · 技术社区  · 7 年前

    我有一个字符串,我想用新值替换现有版本号字符串,但sed只替换第一次出现的版本号字符串,而不是全部。

    我也尝试过使用g标志,即。

    输入

    Old_Version="1.0.0"
    New_Version="2.0.0"
    SEARCH_STRING="Unique String"
    
    
    echo 'versionString =  isMajor? "Major Version 1.0.0" : "Minor Version 1.0.0"; // Unique String' |
    sed -e "s/$Old_Version\(.*$SEARCH_STRING\)/$New_Version\1/g"
    

    输出

    versionString =  isMajor? "Major Version 2.0.0" : "Minor Version 1.0.0"; // Unique String
    

    正如您在上文中所看到的,它只替换了第1个版本,而不是第2个版本,即。

    所需输出

    versionString =  isMajor? "Major Version 2.0.0" : "Minor Version 2.0.0"; // Unique String
    

    此外,搜索模式字符串可以是行中任何唯一的文本。它不必是行中的最后一个文本/注释。

    任何帮助都将不胜感激。

    1 回复  |  直到 7 年前
        1
  •  3
  •   glenn jackman    7 年前

    这是因为“旧”版本的第二个实例在 .* 正则表达式的一部分。

    我假设您希望限制替换包含搜索字符串的行,在这种情况下,您可以编写

    $ input='versionString =  isMajor? "Major Version 1.0.0" : "Minor Version 1.0.0"; // Unique String'
    $ sed -e "/$SEARCH_STRING/ s/$Old_Version/$New_Version/g" <<<"$input"
    
    versionString =  isMajor? "Major Version 2.0.0" : "Minor Version 2.0.0"; // Unique String
    

    这表示“仅对与SEARCH\u字符串匹配的行,执行s///g命令”


    请注意,点是一个正则表达式特殊字符。由于要匹配文字点,旧版本中的点应该转义,否则可以匹配“19090”之类的内容

    $ sed -e "/$SEARCH_STRING/ s/${Old_Version//./\\.}/$New_Version/g" <<<"$input"
    # ...........................^^^^^^^^^^^^^^^^^^^^^
    

    它使用shell的参数替换语法在点之前插入反斜杠。

    此外,添加单词边界以避免匹配“21.0.0”或“1.0.02”

    $ sed -e "/$SEARCH_STRING/ s/\\<${Old_Version//./\\.}\\>/$New_Version/g" <<<"$input"
    # ...........................^^^.....................^^^