Text Manipulation and Comparison
Practical sed for DevOps
🎯 Learning Objective
By the end of this unit, you'll understand how to use sed to manage configuration files efficiently, handle bulk updates across multiple servers, and safely modify production settings - essential skills for deployment automation and configuration management.
📚 Concept Introduction
Sure, you know sed 's/old/new/g' for simple replacements, but production configuration management requires much more: bulk operations, pattern-based targeting, safe backups, and conditional changes.
Every DevOps engineer eventually faces this reality: configuration files multiply across environments, and manually editing them doesn't scale. You need techniques that can update dozens of configuration files consistently, safely, and quickly.
📁 Pre-created:
test-config.txt- Sample configuration for experimenting with techniquesapp.conf- Practice server configuration fileconfig-files/- Multiplenginxconfiguration files simulating real deployment scenarios
⚡ Bulk Operations That Actually Work
The rookie approach: run sed multiple times, hoping nothing breaks between commands. The professional approach: combine operations into atomic updates.
◆ Multiple Changes, Single Command
Let's see what we're working with:
cat test-config.txt
Now imagine you need to update both the database host and port for a deployment. Here's how to do both changes safely:
sed -e 's/old_host/new_host/g' -e 's/8080/9090/g' test-config.txt
The -e flag lets you stack multiple operations. This changes both the host and port in one atomic operation. If either change fails, the whole command fails - no partial updates that break your system.
◆ Cleaner Syntax for Multiple Operations
sed 's/old_host/new_host/g; s/8080/9090/g' test-config.txt
Semicolons do the same thing but with less typing. This is perfect for deployment scripts where you need multiple configuration changes to happen together or not at all.
🎯 Smart Pattern Targeting
Line numbers are useless in production. Configuration files change, lines move around, and hard-coded line numbers break. Smart DevOps engineers use patterns instead.
◆ Surgical Comment Removal
sed '/^#/d' test-config.txt
This removes all commented lines (/^#/d means "find lines starting with # and delete them"). Perfect for generating clean configuration files from templates that contain lots of comments and examples.
◆ Conditional Replacements
sed '/server/s/localhost/10.0.0.1/g' test-config.txt
This says "only in lines containing server, replace localhost with 10.0.0.1". Notice the precision: other localhost references (like in comments or different contexts) remain untouched. This prevents the disasters that happen when you do global replacements without context.
🛡️ The Golden Rule: Always Have Backups
Here's a career-ending story: engineer runs sed -i on production config, makes a typo, breaks the entire application, and has no backup. The application stays down for hours while they try to remember what the file looked like before.
◆ Safe In-Place Editing
First, see what you're about to change:
cat app.conf
This shows your current configuration. Now make the change safely:
sed -i.bak 's/3000/8080/g' app.conf
The .bak extension is your lifeline. This command modifies the original file but automatically creates app.conf.bak with the original content. If something goes wrong, you can instantly recover.
◆ Verifying Your Changes
Check the updated file:
cat app.conf
Verify your backup exists:
cat app.conf.bak
If you made a mistake, recovery is simple: cp app.conf.bak app.conf. No panic, no downtime, no explaining to your manager why the site is broken.
🔧 Feature Toggles Without Code Deploys
One of the most powerful DevOps techniques: enabling and disabling features by commenting and uncommenting configuration lines. No code changes, no recompilations, just smart configuration management.
◆ Enabling Features
Look at your configuration:
cat test-config.txt
See those commented debug lines starting with #? They represent features that are disabled but ready to enable. Here's how to activate them:
sed 's/^#debug/debug/' test-config.txt
This removes the # from lines starting with #debug, instantly enabling debug mode. Perfect for troubleshooting production issues - you can enable debugging, reproduce the problem, then disable it again.
◆ Disabling Features
Sometimes you need to disable features quickly:
sed '/timeout/s/^/#/' test-config.txt
This finds lines containing timeout and adds # at the beginning, effectively disabling timeout settings. Useful when you suspect timeout configurations are causing issues.
🚀 Production Deployment Reality
Development configurations are chatty and helpful. Production configurations need to be lean and fast. This means disabling all the debug logging that helped during development but would overwhelm your production logs.
◆ Identifying What to Clean Up
grep "debug" /home/laborant/config-files/nginx-prod.conf
This shows all the debug-related lines in your production config. These lines are helpful during development but become performance killers and security risks in production.
💡 Real-World Applications
These techniques solve actual production problems:
- Deployment automation: Use
-efor atomic configuration updates across multiple settings - Environment promotion: Use pattern-based addressing to change only relevant settings when promoting from staging to production
- Safe updates: Use
-i.bakto ensure you can always roll back configuration changes - Feature toggles: Use commenting/uncommenting to enable or disable features without code deploys
- Configuration cleanup: Use pattern matching to remove development-specific settings from production configs
The difference between knowing basic sed and these advanced techniques is the difference between spending weekends manually editing configuration files and having automated, reliable deployment processes.
In the next unit, we'll explore how awk can help you analyze logs and process structured data - completing your text processing toolkit for production environments.
Powerful Data Processing with awk
🎯 Learning Objective
By the end of this unit, you'll understand how to use awk to extract insights from log files, calculate performance metrics, and generate professional reports - essential skills for monitoring application health and debugging production issues.
📚 Concept Introduction
You already know basic awk field extraction like awk '{print $2}', but production log analysis requires much more: filtering data based on conditions, calculating metrics, and generating formatted reports.
Every DevOps engineer hits this wall: log files contain treasure troves of insights, but only if you know how to mine them efficiently. Basic tools show you data; advanced awk techniques show you patterns, trends, and answers to business questions.
📁 Pre-created:
test-data.txt- Sample structured data for learning techniquesaccess.log- Realistic web server log for practicing real-world scenarios
🎯 Smart Data Filtering
Dumping all log lines is like drinking from a fire hose. Professional log analysis starts with precise filtering to find exactly what matters.
◆ Finding the Signal in the Noise
Let's see what data we're working with:
cat test-data.txt
This shows user activity with usernames, status, and response times. In production, this could be API calls, database queries, or any structured operation data.
Now, find only the successful operations:
awk '$2 == "successful"' test-data.txt
This filters to show only rows where the second field equals successful. Instantly, you've eliminated noise and focused on what worked.
Here's where it gets powerful - find slow successful operations:
awk '$3 > 200' test-data.txt
This shows only records where response time (field 3) exceeds 200ms. These are your performance bottlenecks hiding in plain sight.
◆ Combining Conditions Like a Pro
awk '$2 == "successful" && $3 > 500' test-data.txt
This finds successful operations that were still slow. This is critical data: your system didn't fail, but users had a bad experience. The && operator lets you slice data with surgical precision.
📊 Turning Data into Insights
Raw numbers tell stories, but only if you know how to make them talk. This is where awk transforms from a text processing tool into a data analysis powerhouse.
◆ Counting What Matters
How many successful operations happened?
awk '$2 == "successful" { count++ } END { print "Successful operations:", count }' test-data.txt
Let's decode this step by step:
$2 == "successful"- This is your filter: only process successful operations{ count++ }- For each matching line, increment our counterEND { print ... }- After processing everything, show the final count
This pattern (filter → action → report) is the foundation of all professional log analysis.
◆ Calculating Totals
What's the total response time for all successful operations?
awk '$2 == "successful" { total += $3 } END { print "Total time:", total "ms" }' test-data.txt
Breaking this down:
$2 == "successful"- Same filter as before{ total += $3 }- Add each response time to our running totalEND { print ... }- Show the accumulated total
This gives you the raw material for deeper analysis.
◆ The Money Shot: Averages
Here's what managers really want to know:
awk '$2 == "successful" { total += $3; count++ } END { print "Average:", total/count "ms" }' test-data.txt
This does three things in one pass:
- Filters for successful operations
- Accumulates both sum and count
- Calculates average response time
But production code needs error handling:
awk '$2 == "successful" { total += $3; count++ } END { if(count > 0) print "Average:", total/count "ms"; else print "No data found" }' test-data.txt
The if(count > 0) prevents crashes when no data matches your filter. This is the difference between scripts that work in demos and scripts that work in production.
📋 Professional Output Formatting
Raw numbers look amateurish in reports. Professional awk users format output that looks intentional and polished.
◆ Precise Number Formatting
Instead of showing 245.666667ms, show 245.7ms:
awk '$2 == "successful" { total += $3; count++ } END { printf "Average: %.1f ms\n", total/count }' test-data.txt
The printf function gives you control:
%.1fformats numbers with exactly 1 decimal place\nadds a proper newline- The result looks professional in reports
◆ Creating Dashboard-Style Output
awk '{ printf "%-10s %10s %8s\n", $1, $2, $3 }' test-data.txt
This creates nicely aligned columns where %-10s left-aligns usernames in 10 characters, and %10s right-aligns status in 10 characters. Your output will look intentional instead of accidental.
🔍 Real-World Log Analysis
Let's analyze actual web server logs - the kind of data you'll encounter during incidents and performance reviews.
◆ Understanding Your Traffic
Look at the web server log:
cat access.log
This shows real web server log format: IP addresses, HTTP methods, URLs, status codes, response times, and timestamps. This is the raw material of web application monitoring.
Find performance problems hiding in your logs:
awk '$5 > 500' access.log
This shows requests that took longer than 500ms. These are the requests that make users complain about "slow site" performance.
◆ Error Rate Analysis
Count how many requests returned errors:
awk '$4 >= 400 { count++ } END { print "Error requests:", count+0 }' access.log
Let's break this down:
$4 >= 400filters for HTTP error codes (400, 404, 500, etc.){ count++ }increments our error counterEND { print ... }reports the final countcount+0ensures we print0instead of blank when no errors exist
This gives you error rates that you can track over time and compare across deployments.
Now let's practice counting error requests:
💡 Real-World Applications
These techniques solve actual production problems:
- Performance monitoring: Filter slow requests to identify bottlenecks before users complain
- Error rate tracking: Count errors over time to detect degrading service quality
- Capacity planning: Calculate average response times to predict when you need more resources
- Incident investigation: Combine filters to isolate specific problems during outages
- Business reporting: Generate formatted metrics that managers can actually understand
The difference between knowing basic awk field extraction and these advanced techniques is the difference between being a log viewer and being a data detective who can solve problems and answer business questions.
In the next unit, we'll explore file comparison with diff and contextual searching with grep - completing your advanced text manipulation toolkit for production troubleshooting.
Comparing Files with diff and Contextual grep
🎯 Learning Objective
By the end of this unit, you'll understand how to use diff to spot critical configuration differences between environments and grep to investigate errors with proper context - essential skills for preventing deployment disasters and debugging production incidents.
📚 Concept Introduction
You already know basic diff and grep, but production troubleshooting requires more advanced techniques: comparing configurations between environments, finding errors with proper context, and investigating incidents systematically.
Every DevOps engineer needs these skills for comparing configurations safely and investigating incidents with precision. Basic grep finds error lines, but contextual grep shows you what caused them. Basic diff shows changes, but unified diff shows you the impact.
📁 Pre-created:
config-dev.conf- Development environment configurationconfig-prod.conf- Production configuration with critical differencesapplication.log- Real application log containing errors and context
🔍 Spotting Critical Configuration Differences
Configuration drift kills deployments. What works in development fails in production because of subtle configuration differences that manual inspection misses.
◆ Understanding What You're Comparing
Let's examine our environments:
cat config-dev.conf
This shows your development configuration - the setup that developers use and test against.
cat config-prod.conf
This shows production configuration with additional security, different ports, and SSL settings that production requires.
◆ Basic Difference Detection
diff config-dev.conf config-prod.conf
This shows differences, but the output is cryptic. You get line numbers and change markers that require mental translation. Fine for simple comparisons, but inadequate when you need to understand the impact quickly.
◆ Professional Difference Analysis
diff -u config-dev.conf config-prod.conf
The unified format (-u) transforms diff into a professional tool:
- Lines starting with
-show what's in development but missing in production - Lines starting with
+show what's added in production - Context lines help you understand where changes occur
- The format is readable by humans and tools alike
This is the format used in code reviews, deployment docs, and incident reports.
◆ Smart Whitespace Handling
Sometimes files have identical content but different formatting:
diff -w config-dev.conf config-prod.conf
The -w option ignores whitespace differences, focusing on actual content changes. This prevents false alarms when files have different indentation or spacing but identical functionality.
For more precise control:
diff -b config-dev.conf config-prod.conf
The -b option ignores changes in whitespace amount but still catches significant formatting differences. Perfect for configuration files where spacing might vary but content matters.
📖 Investigating Incidents with Context
Finding an error line in logs is easy. Understanding what caused it requires context. This is where basic grep falls short and contextual grep becomes essential.
◆ The Problem with Basic Error Hunting
Look at our application log:
cat application.log
This shows a typical application log with startup messages, normal operations, and errors scattered throughout.
Find the errors:
grep "ERROR" application.log
You found the errors, but you've lost the story. What was the application doing when it failed? What happened after the error? Basic grep gives you individual puzzle pieces without showing the picture.
◆ Understanding Error Consequences
grep -A 2 "ERROR" application.log
The -A 2 (After 2) option shows:
- The error line itself
- 2 lines that follow each error
- How the application responded to the failure
This tells you whether errors were recoverable, caused cascading failures, or triggered recovery mechanisms.
◆ Finding Error Triggers
grep -B 1 "ERROR" application.log
The -B 1 (Before 1) option reveals:
- What the application was doing when it failed
- The immediate trigger for each error
- Patterns in what causes problems
This is often more valuable than the error message itself.
◆ Complete Incident Investigation
grep -B 1 -A 2 "ERROR" application.log
Combining before and after context gives you the complete error story:
- What triggered the problem (before)
- What went wrong (the error)
- How the system responded (after)
For symmetric context, use the shorthand:
grep -C 2 "ERROR" application.log
The -C 2 (Context 2) option shows 2 lines both before and after each match, giving you comprehensive incident context.
🛠️ Real Production Scenarios
Let's practice the workflows you'll use during actual incidents and deployments.
◆ Incident Investigation with Context
When production breaks, you need to understand the sequence of events. Error messages alone don't tell the complete story.
◆ Advanced Problem Pattern Detection
Real incidents often involve multiple related issues:
grep -E "(ERROR|WARN)" application.log
The -E flag enables extended regular expressions, letting you search for multiple patterns. This finds all problematic entries, not just errors.
Combine with context for comprehensive analysis:
grep -C 1 -E "(ERROR|WARN)" application.log
This shows all errors and warnings with surrounding context, revealing the complete timeline of system degradation during incidents.
💡 Real-World Applications
These techniques solve actual production problems:
- Pre-deployment validation: Use
diff -uto review configuration changes before they go live - Environment synchronization: Use
diff -wto identify content differences while ignoring formatting - Incident investigation: Use
grep -Cto understand error sequences and cascading failures - Root cause analysis: Use
grep -Bto find what triggers recurring problems - Impact assessment: Use
grep -Ato understand how errors affect subsequent operations - Configuration auditing: Use
diffto detect configuration drift between servers
The difference between knowing basic text tools and these advanced techniques is the difference between hunting randomly through files and conducting systematic investigations that actually solve problems.
You've now mastered the essential text manipulation toolkit: sed for editing, awk for data processing, diff for comparison, and contextual grep for investigation. These skills form the foundation of effective DevOps troubleshooting and system administration.
- Previous lesson
- Mastering tail, xargs, and find
- Next lesson
- Network, Web, and Firewall Inspection