使用sed更改匹配后的第一个匹配项

时间:2015-09-03 18:27:04

标签: bash sed

我已经找到了在匹配后让sed替换的语法,但它会替换匹配后的所有实例。有人可以告诉我我在这里做错了什么。我知道这是一些小事,但我似乎无法接受它。

sed -e "0,/\#NOTE/!  s/$NEW_VVER/$CURRENT_VER/" FILE1 > FILE2

我也试过

sed -e "0,/\#NOTE/!  s/$NEW_VVER/$CURRENT_VER/1" FILE1 > FILE2

以下是sed命令及其要更改的数据的完整行。

sed -e "0,/\#NOTE/!  s/$NEW_VVER/$CURRENT_VER/" -e "0,/\#NOTE/!  s/$NEW_VER/$VER/" -e "0,/\#NOTE/!  s/$EVEN_LENGTH/$OLD_EVEN_LENGTH/" -e "0,/\#NOTE/!  s/$ODD_LENGTH/$OLD_ODD_LENGTH/" -e "0,/\#NOTE/!  s/$START_DIGIT/$OLD_START_DIGIT/" -e "0,/\#NOTE/!  s/$STRING/$OLD_STRING/ FILE1 > FILE2"

基本上它应该找到字符串"#NOTE"并仅替换匹配后的第一个实例。

    #CHANGE THESE EVERY VERSION
#NOTE: Don't forget to add the needed variables to the version arguments. 
   DEFAULT_VERSION = REPVVER
   EVEN_LENGTH = REPELENGTH 
   ODD_LENGTH = REPOLENGTH  
   CURR_VERSION = "REPVVER"
   START_DIGIT = REPSTARTDIGIT
###########################################
例如,它应该找到字符串"#NOTE"并替换" REPVVER"带有新值的字符串。但它不仅会取代那一个,而且会取代所有追随者。

2 个答案:

答案 0 :(得分:3)

sed -e '/#NOTE/!b' -e ':a' -e "s/$NEW_VVER/$CURRENT_VER/;t trail" -e 'n;ba' -e ':trail' -e 'n;btrail' FILE1 > FILE2
  • posix compliance and oneliner(将所有' -e '替换为多行脚本的新行(同样为",并将'替换为"以进行变量解释)
  • NEW_VVER之后更改#NOTE的第一次出现但不在同一行上更改(假设#note是注释行)。林恩可能在#NOTE
  • 之后排第50位
  • 假设NEW_VVERCURRENT_VER的内容符合正则表达式(转发类似&的元字符)

答案 1 :(得分:2)

这是一个相对粗略的方法:

sed -e "/\#NOTE/,/./  s/$NEW_VVER/$CURRENT_VER/" FILE1 > FILE2

这将替换限制为包含#NOTE和下一行的行。每行最多执行一次。

此方法假定替换将在#NOTE行上不做任何更改。这个假设适用于您的示例数据,但您必须确定它是否可以接受。

<强>更新

如果执行替换的行不会紧跟#NOTE,并且您可以依赖$NEW_VVER的值不包含任何正则表达式元字符,那么你可以通过上面的变化来做到这一点:

sed -e "/\#NOTE/,/$NEW_VVER/  s/$NEW_VVER/$CURRENT_VER/" FILE1 > FILE2

在这种情况下,替换适用的行的范围从一个匹配的/\#NOTE/开始,并以匹配/$NEW_VVER/的下一个匹配结束。如上所述,这假设替换将在/\#NOTE/行中没有任何变化。

相关问题