0

This is a bit of a follow-on from How to use sed to replace only the first occurrence in a file? but with a more targeted ask. Given a file

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

The goal is to replace only the first line containing Apple with a new line containing a fixed string (Banana) followed by a bash variable. In the new output, line 2 is now:

Banana: newdata/data.txt

Here is the most recent attempt...

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

However, this produces the error:

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

I think I need the double quotes around $BananaVariable to escape so that it can insert the actual string rather than "BananaVariable", but I think those double quotes are causing the problem. (OS is CentOS 7, sed is GNU version)

so860
  • 408
  • 3
  • 12

3 Answers3

1

From man sed:

/regexp/
       Match lines matching the regular expression regexp.

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

So in your original command replace the first two bars | with slash / (equivalently, replace the first | with \|):

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

You can also shorten the command:

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

output:

Peach: data/file1.txt
Banana: newdata/data.txt
Pear: data/file3.txt
Apple: data/file4.txt
builder-7000
  • 7,131
  • 3
  • 19
  • 43
  • 1
    You should drop the double quotes around `$BananaVariable` as it renders the variable effectively unquoted. – Benjamin W. May 29 '18 at 20:05
  • @Sergio Your first suggestion works correctly and involves the fewest changes to the current code -- thanks! Your second suggestion is the most economic solution proposed (so far). – so860 May 30 '18 at 15:18
0

It is easier with 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
anubhava
  • 761,203
  • 64
  • 569
  • 643
0

This might work for you (GNU sed):

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

If a line is not between the front of the file until a line containing Apple print as normal. Otherwise change the line containing Apple to the required string using a variable.

potong
  • 55,640
  • 6
  • 51
  • 83