使用sed在bash脚本中的可能关键字之间更改文本

时间:2018-12-14 13:28:59

标签: bash shell unix sed

我的input文件包含一些需要更改的文本。例如,它有几种可能性;

CONSTANT change/me !KEY2 !KEY3
CONSTANT change/me 
CONSTANT change/me !DIFFERENTKEY

始终有一个不变的常数键(即CONSTANT)。在需要替换的文本之后,还可能存在不同的关键字。这些用感叹号(!)表示,并且可能没有其他关键字或数千个关键字。我只想替换CONSTANT之后的文本以及以!开头的所有可能的键。最好使用sed

以下是我的预期输出。 change/me中的input必须替换为changed;

CONSTANT changed !KEY2 !KEY3
CONSTANT changed 
CONSTANT changed !DIFFERENTKEY

我曾尝试在SO的答案(hereherehere)中找到不同的方法,但似乎无法弄清楚。我最接近的是来自this链接。

sed -r 's/(^CONSTANT) (.+?) (\!.*$)/\1 changed \3/g' input

导致的结果;

CONSTANT changed !KEY2
CONSTANT change/me
CONSTANT changed !DIFFERENTKEY

我尝试了不同的组合,但此时感觉就像我只是在黑暗中拍摄。

条件:

  • CONSTANT不变
  • change/me是任意文本也可以是 blahblah需要替换
  • 不必!KEY是 礼物
  • 一个!KEY可以存在并且可以是多个,但是 总是与空间隔开。我想维持CONSTANT及其他 可能有!KEY个。

2 个答案:

答案 0 :(得分:1)

第三个(\!*.*$)被强制以!开头,并且第2行不匹配。

请注意,(.+?) (\! ...使sed搜索(.+?)!...为止的最长序列,这就是!KEY2丢失的原因。

必填:change/me绝不包含!,以使下面的解决方案有效。

尝试一下:

sed -r 's/(^CONSTANT) ([^!]+?) *(\!.*|.*)$/\1 changed \3/g' input

输出

CONSTANT changed !KEY2 !KEY3
CONSTANT changed 
CONSTANT changed !DIFFERENTKEY

答案 1 :(得分:1)

不要理会整行内容,是否在要更改的文本之后出现其他内容都没有关系:

sed 's@^CONSTANT change/me@CONSTANT changed@'

我使用@作为分隔符,而不是通常的/,以避免不得不转义/中的change/me

您可以try it here

如果change/me文本有所不同,但从不包含空格,则可以改用以下内容:

sed -E 's@^CONSTANT [^ ]+@CONSTANT changed@'

(对于旧版GNU sed,您将要使用-r标志而不是-E

您可以try it here