Introduction

sed is a very powerful tool for editing configuration files. The examples below use it extensively, including the -i flag for editing configuration files in place. To avoid mistakes, first examine your changes by comparing sed’s output with the original file:

sed $commands $file | diff -u $file -

Recipes

Comment a line

Form:

sed -i "/$pattern/s/^/#/" $file

Example:

sed -i '/^PermitRootLogin yes/s/^/#/' /etc/ssh/sshd_config

Uncomment a line

Form:

sed -i "/$pattern/s/^#//" $file

Example:

sed -i '/^#net.ipv4.ip_forward=1/s/^#//' /etc/sysctl.conf

Add a new line

Form:

echo $line >> $file

Example:

echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.profile

Change a line

Form:

sed -i "/$pattern/c\\
$replacement
" $file

Example:

sed -i '/^DNS1=/c\
DNS1=1.1.1.1
' /etc/sysconfig/network-scripts/ifcfg-eth0

Add a line after an existing one

Form:

sed -i "/$pattern/a\\
$replacement
" $file

Example:

sed -i '/^DNS1=/a\
DNS2=1.0.0.1
' /etc/sysconfig/network-scripts/ifcfg-eth0

Multiple edits

Form:

sed -i "
# Optional comment describing command_1
$command_1
# Optional comment describing command_n
$command_n
" $file

Example:

sed -i '
# Forward IPv4 packets
/^#net.ipv4.ip_forward=1/s/^#//
# Forward IPv6 packets
/^#net.ipv6.conf.all.forwarding=1/s/^#//
' /etc/sysctl.conf

Edit a group of lines

Form:

sed -i "/$begin_pattern/,/$end_pattern/$function" $file

Example:

# Disable Apache indexes in /var/www
sed -i '/<Directory \/var\/www\/>/,/<\/Directory>/s/ Indexes//' \
	/etc/apache2/apache2.conf

Combining actions

Form:

sed -i "/$pattern/{
$function_1
$function_n
}" $file

Example:

# Change DNS1 and add DNS2 after it
sed -i '/^DNS1=/{
a\
DNS2=1.0.0.1
c\
DNS1=1.1.1.1
}' /etc/sysconfig/network-scripts/ifcfg-eth0

Tips

  • Do sed $commands $file > $file.new && mv $file.new $file instead of using the -i flag for portability.

  • The -n option can be used to output only the lines affected by the sed commands instead of the entire file.

  • Use the p function combined with -n to print matching lines (like grep).

  • Use the i\ function instead of a\ to add a line before an existing one.

  • If there are many forward slashes in your pattern, you can use a different delimiter:

# Before
sed -n '/<Directory \/var\/www\/>/p' /etc/apache2/apache2.conf

# After (using | as a delimiter)
sed -n '\|<Directory /var/www/>|p' /etc/apache2/apache2.conf