2

I have a problem that is very similar to this SO thread: how to replace all lines between two points and subtitute it with some text in sed

Consider a problem like this:

$ cat file
BEGIN
hello
world
how
are
you
END

$ sed -e '/BEGIN/,/END/c\BEGIN\nfine, thanks\nEND' file
BEGIN
fine, thanks
END

How might I inject text that I have saved to a variable like:

str1=$(echo "This is a test")

How can I inject str1's output in the place of fine, thanks, like:

sed -e '/BEGIN/,/END/c\BEGIN\n$str1\nEND' file  # fails to work as hoped

I also want to save the output to overwrite the file.

John Stud
  • 1,506
  • 23
  • 46

2 Answers2

1

Sure is easy in awk.

Given:

cat file
ABC
BEGIN
hello
world
how
are
you
END
XYZ

You can do:

str='TEST'

awk -v r="$str" -v f=1 '/^BEGIN$/{print $0 "\n" r; f=0}
/^END$/{f=1} f' file

Prints:

ABC
BEGIN
TEST
END
XYZ

If you want to embed another file in between those marks:

awk -v f=1 -v fn='ur_file' '/^BEGIN$/{
    print $0
    while ((getline<fn)>0) {print}
    f=0}
/^END$/{f=1} f' file
dawg
  • 98,345
  • 23
  • 131
  • 206
  • Thanks for the input -- this gives me an error, however: `-bash: /usr/bin/awk: Argument list too long` as I have to paste quite a lot of text in. – John Stud Jul 07 '21 at 21:25
  • An alternative is to do like: `awk -v r="cat file.html ...`; but then I want to write the work awk does to the file. – John Stud Jul 07 '21 at 21:35
1

You can probably use this sed:

sed -e '/BEGIN/,/END/ {//!d; /BEGIN/r file.html' -e '}' file

This will insert content of file.html file between BEGIN and END. To save changes back to file:

sed -i -e '/BEGIN/,/END/ {//!d; /BEGIN/r file.html' -e '}' file
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • Quick question in case you are still monitoring -- how to add a return `\n` to this such that there is a clear line break between the BEGIN and END? – John Stud Jul 08 '21 at 01:54
  • 1
    Try: `sed -e '/BEGIN/,/END/ {//!d; /BEGIN/r file.html' -e ';s/^/\n/;}' file` – anubhava Jul 08 '21 at 04:51