How to Use SED for Multiline Pattern Replacement in XML Files: Uncommenting AJP Connector Configuration


2 views

When working with configuration files like server.xml in Tomcat, we often need to modify multiline commented sections. The standard SED approach fails because it's designed for single-line patterns by default.

The issue with your initial commands:

sudo sed -i 's:::' /myfile.xml

And the newline attempt:

sudo sed -i 's:::' /myfile.xml

Both fail because:
1. SED processes input line by line
2. The backslash escape sequence interpretation differs in patterns

Option 1: Using SED with Hold Buffer

This method uses SED's pattern space and hold buffer:

sudo sed -i '///}' /myfile.xml

Option 2: Perl One-liner

For more complex multiline patterns, Perl often works better:

sudo perl -i -pe 'BEGIN{undef $/;} s///g' /myfile.xml

Option 3: Using awk

awk provides another alternative for multiline processing:

sudo awk -v RS='' '{gsub(//, "")} 1' /myfile.xml > tmp && mv tmp /myfile.xml

When working with XML files:
- Always back up the original file first
- Consider using XML-specific tools like xmlstarlet for complex modifications
- Test your changes in a staging environment first

For broader comment removal while preserving XML structure:

sudo xmlstarlet ed -d '//comment()' /myfile.xml > tmp && mv tmp /myfile.xml

When working with configuration files like server.xml in Tomcat, we often need to uncomment multi-line blocks. The standard SED approach fails because:

  • By default SED processes one line at a time
  • Newline characters aren't handled intuitively
  • Special characters in XML require proper escaping

Here are three effective methods to handle this scenario:

Method 1: Using the N Command

sudo sed -i '//\\1/}' /path/to/server.xml

This works by:

  1. Finding the starting pattern '<!--'
  2. Using N to append the next two lines into pattern space
  3. Performing the substitution across all three lines

Method 2: Using Perl for Complex Replacements

sudo perl -i -pe 'BEGIN{undef $/;} s///mg' server.xml

Advantages include:

  • Handles variable whitespace between lines
  • More readable regex syntax
  • Better handling of special characters

Method 3: Alternative SED Approach with Hold Space

sudo sed -i -n '
1 {
  h
  n
  n
}
/-->/ {
  x
  s///
  p
  d
}
$ {
  x
  p
}' server.xml
  • Always back up files before in-place editing
  • Test patterns with -n and p flags first
  • Consider XML-specific tools like xmlstarlet for complex cases
  • Be mindful of different SED implementations (GNU vs BSD)

For a complete Tomcat connector uncommenting solution:

#!/bin/bash
CONFIG_FILE="/opt/tomcat/conf/server.xml"
BACKUP_FILE="${CONFIG_FILE}.bak-$(date +%Y%m%d)"

# Create backup
cp "$CONFIG_FILE" "$BACKUP_FILE"

# Perform the uncommenting
sed -i '// {
  // {
    s/-->//
    H
    g
    s/\\n//g
  }
}' "$CONFIG_FILE"

echo "Original saved to $BACKUP_FILE"
echo "Uncommented AJP connector in $CONFIG_FILE"