Skip to content

Network Configuration Diff Exclusions - rConfig V8

Every configuration backup captures a snapshot in time. But not everything in that snapshot matters for change tracking. Timestamps change with every backup. Uptime counters increment constantly. Session IDs are ephemeral. Certificate renewal dates shift. These dynamic elements create false positives in diffs—changes that aren’t really changes.

Diff exclusions solve this problem by filtering out noise so you can focus on what actually matters: intentional configuration modifications tracked by Change Pulse.


You run daily backups of your core routers. Yesterday’s config and today’s config show 47 differences. But when you review the diff:

  • 20 differences are timestamp updates
  • 15 are uptime counter changes
  • 8 are interface packet counters
  • 3 are session IDs
  • 1 is an actual ACL modification

You spent 10 minutes finding the one real change buried in 46 false positives. Multiply this across hundreds of devices and thousands of backups, and diff noise becomes a serious operational burden.

Diff exclusions eliminate this waste.


rConfig provides granular control over how each command’s output is compared. Different commands need different comparison behaviors—operational state commands have more dynamic content than configuration commands.

Navigate to Inventory → Commands → Compare Options

Click the Compare Options button to configure comparison behavior for that specific command.

rConfig V8 command configuration interface displaying Compare Options button for diff exclusion settings

Compare Options button in command settings

OptionPurposeExample Use Case
Compare ExclusionsExclude specific lines/patterns using regexIgnore ! Last configuration change at 12:34:56 timestamps
Compare ContextShow N lines before/after each differenceShow 3 lines of context around changes for readability
Length LimitCompare only first N lines of outputLimit show tech-support comparison to first 1000 lines
Ignore CaseCase-insensitive comparisonTreat Router and router as identical
Ignore Line EndingIgnore CR/LF differencesHandle configs from Windows/Linux/Unix systems
Ignore WhitespaceIgnore spaces, tabs, and indentationIgnore formatting differences, focus on content

Strategy: Start with exclusions and whitespace ignoring for most commands. Add context lines for readability. Use length limits only for extremely verbose commands.


Diff exclusions use regex patterns to identify content that should be ignored during comparison. The format is similar to Policy Definitions but adapted for comparison logic.

// Description of what this exclusion does
#[global]
/regex pattern one/
/regex pattern two/
// Description of command-specific exclusion
#[command-name]
/command-specific pattern/

Structure breakdown:

  1. Description line (required)

    • Starts with // followed by description text
    • Explains what the exclusion does
    • Helps future maintainers understand the pattern’s purpose
  2. Method block (required)

    • Starts with #[method-name]
    • Defines scope of exclusions
    • First block must be #[global]
  3. Regex patterns (one or more)

    • Full regex including delimiters: /pattern/
    • Include any flags: /pattern/i (case-insensitive), /pattern/ms (multiline)
    • One pattern per line

Method Blocks: Global vs. Command-Specific

Section titled “Method Blocks: Global vs. Command-Specific”

#[global] block:

  • Applies to ALL command outputs across all devices
  • Use for universally dynamic content (timestamps, session IDs)
  • Must be the first method block in your exclusions

#[command-name] blocks:

  • Apply only to specific commands
  • Command name must match exactly as stored in database
  • Example: If command is stored as show run, use #[show run], not #[show running-config]
  • Multiple command-specific blocks allowed

Critical: Command names are case-sensitive and must match the database exactly. If exclusions aren’t working, verify the command name first.


Single-line patterns are processed line-by-line for optimal performance. They’re ideal for filtering individual lines of dynamic content.

// Exclude all timestamp variations
#[global]
/^! Last configuration change at.*$/
/^! NVRAM config last updated at.*$/
/^Building configuration.*$/

Matches:

  • ! Last configuration change at 12:34:56 UTC Mon Oct 2 2025
  • ! NVRAM config last updated at 08:15:22 UTC Tue Oct 3 2025
  • Building configuration...
// Exclude uptime from show version
#[show version]
/^.*uptime is.*$/
/^System restarted at.*$/
/^System image file is.*$/

Matches:

  • router1 uptime is 2 weeks, 3 days, 14 hours, 27 minutes
  • System restarted at 04:23:10 UTC Mon Sep 25 2025
  • System image file is "bootflash:cat9k-ios.bin"
// Exclude session details from show run
#[show run]
/^! Session ID:.*$/
/^! Command issued by.*$/
/^Current configuration : \d+ bytes$/

Matches:

  • ! Session ID: admin-12345
  • ! Command issued by user: admin
  • Current configuration : 14523 bytes
// Exclude packet and error counters
#[show interfaces]
/^\s+\d+ packets input, \d+ bytes.*$/
/^\s+\d+ packets output, \d+ bytes.*$/
/^\s+\d+ input errors.*$/
/^\s+\d+ output errors.*$/

Matches:

  • 1234567 packets input, 987654321 bytes, 0 no buffer
  • 9876543 packets output, 123456789 bytes, 0 underruns
// Exclude NTP clock period drift compensation
#[global]
/^ntp clock-period \d+$/

Matches:

  • ntp clock-period 17180127

This value changes constantly as the device adjusts for clock drift.


Multiline patterns handle content spanning multiple lines—certificate blocks, large configuration sections, multi-line statements. They require special regex flags and careful construction.

s flag (dotall):

  • Allows . (dot) to match newline characters
  • Essential for patterns crossing line boundaries
  • Example: /pattern.*content/s

m flag (multiline):

  • Changes ^ to match start of any line (not just string start)
  • Changes $ to match end of any line (not just string end)
  • Example: /^interface.*$/m

Combined: /ms:

  • Use both flags for maximum flexibility
  • Most multiline exclusions need both
  • Example: /^interface.*?^!/ms

CRITICAL: Do NOT use g flag. PHP handles global matching differently than JavaScript—rConfig automatically processes all matches without requiring the g flag.

Certificates span many lines and change when renewed. Exclude them to avoid false positives.

// Exclude private key blocks
#[global]
/^set private-key "-----BEGIN ENCRYPTED PRIVATE KEY-----.*?-----END ENCRYPTED PRIVATE KEY-----"$/ms
// Exclude certificate text from show run
#[show run]
/^crypto pki certificate.*?-----END CERTIFICATE-----"$/ms
// Exclude public keys
#[show run]
/^ssh-rsa AAAA.*?==.*$/ms

Key technique: Use .*? (non-greedy) instead of .* (greedy) to stop at the first closing tag, not the last.

Exclude entire sections that change frequently or contain dynamic data.

// Exclude BGP router configuration blocks
#[global]
/^router bgp \d+.*?^!/ms
// Exclude interface configuration blocks
#[show run]
/^interface .*?^!/ms
// Exclude access-list blocks
#[show run]
/^ip access-list extended .*?^!/ms
// Exclude route-map blocks
#[show run]
/^route-map .*?^!/ms

Pattern explanation: ^interface .*?^!/ms

  • ^interface - Start of line matching “interface”
  • .*? - Non-greedy match of any content (including newlines with s flag)
  • ^! - Stop at line starting with ! (Cisco config section delimiter)
  • /ms - Multiline and dotall flags
// Exclude dynamic key-value pairs
#[show run]
/^service timestamps.*$/m
/^service sequence-numbers$/m
// Exclude banner messages
#[show run]
/^banner motd \^C.*?\^C$/ms
// Juniper: Exclude commit history
#[show configuration]
/^## Last commit:.*$/m
// Aruba: Exclude controller uptime
#[show running-config]
/^controller uptime.*$/m
// HP/Aruba: Exclude time sync
#[show run]
/^time .*$/m

Here’s a production-ready exclusion configuration for Cisco IOS devices:

// Global exclusions for all commands
#[global]
/^! Last configuration change at.*$/
/^! NVRAM config last updated at.*$/
/^ntp clock-period \d+$/
/^.*uptime is.*$/
/^System restarted at.*$/
// Show version specific exclusions
#[show version]
/^System image file is.*$/
/^Configuration register is.*$/
/^\d+K bytes of .*memory\.$/
// Show run specific exclusions
#[show run]
/^! Session ID:.*$/
/^! Command issued by.*$/
/^Building configuration.*$/
/^Current configuration : \d+ bytes$/
// Certificate exclusions for show run
#[show run]
/^crypto pki certificate.*?-----END CERTIFICATE-----"$/ms
/^ssh-rsa AAAA.*?==.*$/ms
// Interface block exclusions
#[show run]
/^interface .*?^!/ms
// Show interfaces exclusions
#[show interfaces]
/^\s+\d+ packets input, \d+ bytes.*$/
/^\s+\d+ packets output, \d+ bytes.*$/
/^\s+\d+ input errors.*$/
/^\s+\d+ output errors.*$/
/^\s+Last input.*$/
/^\s+Last output.*$/

Begin with global exclusions for universal noise (timestamps). Add command-specific exclusions as you identify patterns unique to certain commands.

Use regex101.com to validate patterns:

  1. Set flavor to PCRE (PHP)
  2. Paste sample command output
  3. Enter your regex pattern with flags
  4. Verify it matches expected content only

Always use .*? instead of .* in multiline patterns:

Greedy (wrong):

/^interface .*^!/ms

Matches from first interface to LAST !, capturing multiple blocks.

Non-greedy (correct):

/^interface .*?^!/ms

Matches from interface to FIRST !, capturing one block at a time.

Every exclusion block should have a clear description:

Bad:

#[global]
/^ntp clock-period \d+$/

Good:

// Exclude NTP clock period drift compensation value (changes constantly)
#[global]
/^ntp clock-period \d+$/

Too broad:

/^.*$/

Excludes everything—useless.

Too narrow:

/^! Last configuration change at 12:34:56 UTC Mon Oct 2 2025$/

Only matches exact timestamp—breaks next day.

Just right:

/^! Last configuration change at.*$/

Matches any timestamp on that line.

As device software versions change, exclusion patterns may need updates:

  • New commands with different output formats
  • Changed timestamp formats
  • New dynamic fields introduced

Schedule quarterly reviews of exclusion effectiveness.


Symptom: Pattern should match but diffs still show the content.

Checklist:

  1. Verify command name: #[show run] must match database exactly

    • Check Commands table for exact name
    • Command names are case-sensitive
    • Include any special characters or spaces exactly
  2. Check regex syntax:

    • Delimiters present: /pattern/, not pattern
    • Flags correct: /pattern/ms if multiline
    • Escape special characters: \. for literal dot
  3. Test pattern in isolation:

    • Copy command output to regex101.com
    • Set flavor to PCRE (PHP)
    • Verify pattern matches expected content
  4. Verify method block:

    • #[global] must come first
    • Command-specific blocks after global
    • No typos in block names

Symptom: Important configuration changes are being excluded.

Solution: Make pattern more specific by adding anchors and context.

Too broad:

/interface/

Matches ANY line containing “interface”—excludes important interface config lines.

Better:

/^interface Loopback\d+$/m

Only matches loopback interface declaration lines, not config within interfaces.

Symptom: Multiline content still appears in diffs.

Checklist:

  1. Add s flag: Required for . to match newlines

    /pattern.*content/s
  2. Use non-greedy matching: Add ? after quantifiers

    /start.*?end/ms
  3. Check anchors: ^ and $ need m flag for multiline behavior

    /^interface.*?^!/ms
  4. Verify content structure: View raw config to confirm actual line breaks and delimiters

Symptom: Diffs take a long time to generate.

Possible causes:

  1. Overly complex regex: Nested quantifiers, excessive backtracking
  2. Too many patterns: Hundreds of exclusions per command
  3. Greedy multiline patterns: Using .* instead of .*?

Solutions:

  • Simplify complex patterns
  • Combine related patterns where possible
  • Always use non-greedy matching in multiline patterns
  • Consider limiting diff length if command output is massive

For a visual walkthrough of configuring diff exclusions with real examples, see our YouTube tutorial:

Watch: Configuring Diff Exclusions in rConfig →



// Description
#[global]
/regex pattern one/
/regex pattern two/
// Description
#[command-name]
/command-specific pattern/
FlagNamePurposeExample
sDotall. matches newlines/pattern.*content/s
mMultiline^/$ match line boundaries/^interface.*$/m
iCase-insensitiveIgnore case/router/i
msCombinedBoth multiline and dotall/^block.*?^!/ms

Remember: Never use g flag in rConfig exclusions.

ElementMeaningExample
^Start of line^interface
$End of linebytes$
.Any charactera.c matches abc
.*Zero or more (greedy)a.*z
.*?Zero or more (non-greedy)a.*?z
\dAny digit\d+ matches 123
\sWhitespace\s+ matches spaces/tabs
\SNon-whitespace\S+ matches word