sed:仅将第一个实例替换为包含bash变量的字符串

时间:2018-05-29 19:53:36

标签: regex bash unix sed centos7

这是How to use sed to replace only the first occurrence in a file?的后续内容,但有更具针对性的问题。给定一个文件

Peach: data/file1.txt
Apple: data/file2.txt
Pear: data/file3.txt
Apple: data/file4.txt

目标是仅使用包含固定字符串(Banana)的新行替换包含Apple的第一行,然后使用bash变量。在新输出中,第2行现在是:

Banana: newdata/data.txt

这是最近的尝试......

BananaVariable=newdata
sed -i -E "0,|(Apple).*|{s|(Apple:).*|Banana: "$BananaVariable"/data.txt|}" filename

然而,这会产生错误:

sed: -e expression #1, char 3: unexpected  `,'

我想我需要$ BananaVariable周围的双引号才能转义,以便它可以插入实际的字符串而不是“BananaVariable”,但我认为这些双引号导致问题。 (OS是CentOS 7,sed是GNU版本)

3 个答案:

答案 0 :(得分:1)

来自man sed

/regexp/
       Match lines matching the regular expression regexp.

\cregexpc
       Match  lines  matching the regular expression regexp.  The c may
       be any character.

因此,在原始命令中,使用斜杠|替换前两个条/(等效地,将第一个|替换为\|):

sed -i -E "0,/(Apple).*/{s|(Apple:).*|Banana: $BananaVariable/data.txt|}" filename

您还可以缩短命令:

sed -i -E "0,/^Apple/s|.*|Banana: $BananaVariable/data.txt|" filename

输出:

Peach: data/file1.txt
Banana: newdata/data.txt
Pear: data/file3.txt
Apple: data/file4.txt

答案 1 :(得分:0)

awk

更容易
var='newdata/data.txt'
awk -v v="$var" 'BEGIN{FS=OFS=": "}
!p && $1 == "Apple"{$1="Banana"; $2=v; p=1} 1' file

Peach: data/file1.txt
Banana: newdata/data.txt
Pear: data/file3.txt
Apple: data/file4.txt

答案 2 :(得分:0)

这可能适合你(GNU sed):

sed -i -e '0,/Apple/!b;//cBanana: '"$BananaVariable"'/data.txt' file

如果一行不在文件的正面之间,直到包含Apple的行正常打印。否则,使用变量将包含Apple的行更改为所需的字符串。