0

this is my sample xml file-

<appender name="SYSTEMLOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
  <level>INFO</level>
</filter>
<file>${cassandra.logdir}/system.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
  <fileNamePattern>${cassandra.logdir}/system.log.%i.zip</fileNamePattern>
  <minIndex>1</minIndex>
  <maxIndex>20</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
  <maxFileSize>20MB</maxFileSize>
</triggeringPolicy>
<encoder>
  <pattern>%-5level [%thread] %date{ISO8601} %F:%L - %msg%n</pattern>
</encoder>
</appender>


<!-- DEBUGLOG rolling file appender to debug.log (all levels) -->
<appender name="DEBUGLOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${cassandra.logdir}/debug.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
  <fileNamePattern>${cassandra.logdir}/debug.log.%i.zip</fileNamePattern>
  <minIndex>1</minIndex>
  <maxIndex>20</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
  <maxFileSize>20MB</maxFileSize>
</triggeringPolicy>
<encoder>
  <pattern>%-5level [%thread] %date{ISO8601} %F:%L - %msg%n</pattern>
</encoder>
</appender>

I want to replace -

<file>${cassandra.logdir}/system.log</file>
<fileNamePattern>${cassandra.logdir}/system.log.%i.zip</fileNamePattern>

${cassandra.logdir}/system.log with /var/log/cassandra/system.log

and similarly tag

<file>${cassandra.logdir}/debug.log</file>
<fileNamePattern>${cassandra.logdir}/debug.log.%i.zip</fileNamePattern>

${cassandra.logdir}/debug.log with /var/log/cassandra/debug.log

i tried several method using sed but not able to achieve this. please help me on this to figure out the solution using sed command which i am using in my shell script.

2
  • Don't Parse XML/HTML With Regex. I suggest to use an XML/HTML parser (xmlstarlet, xmllint ...).
    – Cyrus
    Oct 13, 2019 at 21:04
  • So actually, you don't care about XML at all, but want to replace each occurence of ${cassandra.logdir} with /var/log/cassandra? How about a simple sed 's_${cassandra.logdir}_/var/log/cassandra_g?
    – Philippos
    Oct 14, 2019 at 12:26

1 Answer 1

1

I will be assuming that the XML is well-formed and syntactically correct.

Using the XML processor xmlstarlet:

xmlstarlet edit \
    --update '//*[starts-with(text(),"${cassandra.logdir}")]' \
        --expr 'concat("/var/log/cassandra",substring-after(text(),"${cassandra.logdir}"))'  file.xml

This updates the value of any node in the document whose value happens to start with the specific string ${cassandra.logdir}. The update changes the value of the node by concatenating the string /var/log/cassandra with the result of removing the string ${cassandra.logdir} from the original value of the node (in effect replacing the prefix portion of the string with a new value).

The same thing, but using internal variables for the query and replacement strings. Note that these are XPath expressions and therefore must be quoted strings.

xmlstarlet edit \
    --var query '"${cassandra.logdir}"' \
    --var replacement '"/var/log/cassandra"' \
    --update '//*[starts-with(text(),$query)]' \
        --expr 'concat($replacement,substring-after(text(),$query))'  file.xml

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .