36

Say I have a text file like this:

# custom content section
a
b

### BEGIN GENERATED CONTENT
c
d
### END GENERATED CONTENT

I'd like to replace the portion between the GENERATED CONTENT tags with the contents of another file.

What's the simplest way to do this?

smokris
  • 1,622

5 Answers5

48
lead='^### BEGIN GENERATED CONTENT$'
tail='^### END GENERATED CONTENT$'
sed -e "/$lead/,/$tail/{ /$lead/{p; r insert_file
        }; /$tail/p; d }"  existing_file
Peter.O
  • 3,093
7
newContent=`cat new_file`
perl -0777 -i -pe "s/(### BEGIN GENERATED CONTENT\\n).*(\\n### END GENERATED CONTENT)/\$1$newContent\$2/s" existing_file
smokris
  • 1,622
6

Using a heredoc and the ed line editor:

ed -s FILE1 <<EOF
/### BEGIN GENERATED/+,/### END GENERATED/-d
/### BEGIN GENERATED/ r FILE2
w
q
EOF

The first line inside the heredoc is to delete (d) the line after (+) the ### BEGIN GENERATED and the line before (-) the ### END GENERATED...

The second line is to insert FILE2 after the line ### BEGIN GENERATED.

Destroy666
  • 12,350
4

Warning: This is definitely not the simplest way to do it. (EDIT: bash works; POSIX grep is fine too)

If the main text is in file "main" and the generated content is in file "gen", you could do the following:

#!/bin/bash
BEGIN_GEN=$(cat main | grep -n '### BEGIN GENERATED CONTENT' | sed 's/\(.*\):.*/\1/g')
END_GEN=$(cat main | grep -n '### END GENERATED CONTENT' | sed 's/\(.*\):.*/\1/g')
cat <(head -n $(expr $BEGIN_GEN - 1) main) gen <(tail -n +$(expr $END_GEN + 1) main) >temp
mv temp main
Dr Kitty
  • 544
0

Here is a Bash script using ed line editor to replace / update a part of multiline text in a text file with automatically generated content (eg: Table of contents)

replace.sh

#!/usr/bin/env bash
# -*- coding: UTF-8 -*-
#
# github   : https://github.com/JV-conseil
# www      : https://www.jv-conseil.net
# author   : JV-conseil
#===============================================

_lines=""

for i in {1..10}; do _lines+=$'\n'"${i}. ""$(openssl rand -hex 12)" done

ed -s "./sample.md" <<EOF /## BEGIN GENERATED/+,/## END GENERATED/-d /## BEGIN GENERATED/a ${_lines}

. wq EOF

sample.md

# How to replace part of a text file between markers with another text file?

Here is a Bash script using [ed line editor](https://www.gnu.org/software/ed/manual/ed_manual.html "GNU manual for ed line editor") to replace / update a part of multiline text in a text file with automatically generated content (eg: Table of contents)

BEGIN GENERATED

  1. d5c10e45943b196b005771f1
  2. bc56de530fbf5342d55203b4
  3. 9608f31a09c2ece9c9cee4dd
  4. 54e361257aecce0a937211c0
  5. c4b2edf88293df0747694c37
  6. a80275accc9b2bc72d55efcd
  7. 3a2e2fec5da23b415569de00
  8. 524655319a05e7dd1f48e6a5
  9. 879d17e9e611d163e5a85b02
  10. 80d311a786efcd9d01da86f6

END GENERATED

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris et libero eu nunc dapibus volutpat. Proin eu neque eu orci volutpat bibendum...