🐧

sed

4 notes  •  Linux & Server Admin

sed: Insert Lines Before and After a Pattern Match

Use sed to insert text before or after a line that matches a pattern, without opening the file in an editor.

Insert a Line Before a Match

# Insert "NEW LINE" before every line containing "PATTERN"
sed -i '/PATTERN/i NEW LINE' file.txt

# Example: insert a comment before a config directive
sed -i '/^ServerName/i # Primary server name' /etc/apache2/apache2.conf

Insert a Line After a Match

# Insert "NEW LINE" after every line containing "PATTERN"
sed -i '/PATTERN/a NEW LINE' file.txt

# Example: add a directive after the opening VirtualHost tag
sed -i '/<VirtualHost \*:80>/a\    ServerAdmin admin@example.com' site.conf

Replace a Line Containing a Pattern

# Replace entire matching line
sed -i '/PATTERN/c\NEW CONTENT' file.txt

Preview Before Saving (Dry Run)

# Show result without modifying the file (omit -i)
sed '/PATTERN/i NEW LINE' file.txt

Remove Windows Line Endings (^M / \r) from Linux Files

Files transferred from Windows to Linux often contain \r\n (CRLF) line endings instead of Unix \n (LF). The ^M characters visible in editors are the carriage return (\r). Here's how to remove them.

Remove ^M from a Single File with sed

sed -i -e 's/
$//' filename.sh

Remove ^M Using dos2unix

sudo apt-get install -y dos2unix
dos2unix filename.sh

# Convert multiple files
dos2unix *.sh

Remove ^M from All PHP Files Recursively

find . -type f -name "*.php" -exec dos2unix {} \;
# or with sed:
find . -type f -name "*.php" -exec sed -i -e 's/
$//' {} \;

Verify

# Check for carriage returns
file filename.sh
# "ASCII text" = clean; "CRLF line terminators" = needs fixing

cat -A filename.sh | head -5
# Clean lines end with $; Windows lines end with ^M$

Bulk Replace Domain Name in Files with sed and grep

How to find and replace an old domain name across multiple files in a directory, excluding specific subdirectories like git metadata or media files.

Replace Domain in All Files (with Exclusions)

grep -rl "https://olddomain.com" . \
  --exclude-dir=.git \
  --exclude-dir=media \
  | xargs sed -i 's,https://olddomain.com,https://newdomain.com,g'

Preview Changes First (Dry Run)

# See which files contain the old domain
grep -rl "https://olddomain.com" . --exclude-dir=.git

# See the actual lines that will change
grep -rn "https://olddomain.com" . --exclude-dir=.git

Replace in a Specific File Type

# Only PHP files
grep -rl "olddomain.com" . --include="*.php" \
  | xargs sed -i 's/olddomain\.com/newdomain.com/g'

Notes

  • Use commas (,) instead of slashes in the sed pattern when URLs contain slashes.
  • Always do a dry run (no -i) first to preview changes before modifying files.
  • Back up the directory before bulk replacements: cp -r . ../backup

Combine Multiple sed Substitutions in One Command

When you need to apply multiple sed substitutions to a file, use the -e flag to chain them in a single command instead of running sed multiple times.

Using Multiple -e Flags

sed -i -e 's/File//g' -e 's/MINvac.pdb//g' input.txt

Using a Semicolon Separator

sed -i 's/foo/bar/g; s/baz/qux/g' input.txt

Using a sed Script File

# Create a script file with multiple commands
cat > fix.sed << 'EOF'
s/File//g
s/MINvac.pdb//g
s/old_hostname/new_hostname/g
EOF

# Apply the script
sed -i -f fix.sed input.txt

Apply to All Files in a Directory

find . -name "*.txt" -exec sed -i -e 's/foo/bar/g' -e 's/baz/qux/g' {} \;

Preview Without Modifying

# Omit -i to print to stdout
sed -e 's/File//g' -e 's/MINvac.pdb//g' input.txt