Lesson  in  Test Linux for DevOps Engineers

Text Manipulation and Comparison

Master advanced sed stream editing, powerful awk data processing, file comparison and grep techniques.

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 techniques
  • app.conf - Practice server configuration file
  • config-files/ - Multiple nginx configuration 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 -e for 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.bak to 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 techniques
  • access.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 counter
  • END { 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 total
  • END { 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:

  • %.1f formats numbers with exactly 1 decimal place
  • \n adds 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 >= 400 filters for HTTP error codes (400, 404, 500, etc.)
  • { count++ } increments our error counter
  • END { print ... } reports the final count
  • count+0 ensures we print 0 instead 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 configuration
  • config-prod.conf - Production configuration with critical differences
  • application.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 -u to review configuration changes before they go live
  • Environment synchronization: Use diff -w to identify content differences while ignoring formatting
  • Incident investigation: Use grep -C to understand error sequences and cascading failures
  • Root cause analysis: Use grep -B to find what triggers recurring problems
  • Impact assessment: Use grep -A to understand how errors affect subsequent operations
  • Configuration auditing: Use diff to 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.