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


11 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"