Alex Rivera | Logout

Replace delimited block of text in file with the contents of another file

Asked 2010-04-23T15:11:16.647
9

I need to write a simple script to replace a block of text in a configuration file with the contents of another file.

Let's assume with have the following simplified files:

server.xml

<?xml version='1.0' encoding='UTF-8'?>
<Server port="8005" shutdown="SHUTDOWN">
  <Service name="Catalina">
    <Connector port="80" protocol="HTTP/1.1"/>
    <Engine name="Catalina" defaultHost="localhost">
      <!-- BEGIN realm -->
        <sometags/>
        <sometags/>
      <!-- END realm -->
      <Host name="localhost" appBase="webapps"/>
    </Engine>
  </Service>
</Server>

realm.xml

<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
       resourceName="UserDatabase"/>

I want to run a script and have realm.xml replace the contents between the <!-- BEGIN realm --> and <!-- END realm --> lines. If realm.xml changes then whenever the script is run again it will replace the lines again with the new contents of realm.xml. This is intended to be run in /etc/init.d/tomcat on startup of the service on multiple installations on which the realm is going to be different.

I'm not so sure how can I do this simply with awk or sed.

Edit
Report

1 Answer

4

you can use awk

awk 'FNR==NR{ _[++d]=$0;next}
/BEGIN realm/{
  print
  for(i=1;i<=d;i++){ print _[i] }
  f=1;next
}
/END realm/{f=0}!f' realm.xml server.xml > temp && mv temp server.xml

realm.xml is passed to awk as the first file. FNR==NR means getting the records of the first file passed in and store to variable _. awk will process the next file once FNR!=NR. if awk finds /BEGIN realm/, print the BEGIN realm line, then print what is stored in _. By setting a flag (f) to 1, the rest of the lines after BEGIN realm will not be printed until /END realm/ is detected.

answered 2010-04-23T15:23:16.467

Your Answer