Using sed to replace multi-line strings in apache2.conf file

As part of my Bash server setup script, I am trying to lock down the default apache www website.

I want to convert this:

<Directory /var/www> Options Indexes FollowSymLinks

To this:

<Directory /var/www> Options -Indexes -FollowSymLinks -ExecCGI

Since Options Indexes FollowSymLinks is mentioned multiple times in the file, I need the search and replace to include the previous line.

I've tried the below sed command, using backslash to escape slashes, but it doesn't replace anything:

cat /etc/apache2/apache2.conf | sed 's/[<Directory \/var\/www\/>]\n Options Indexes FollowSymLinks/[<Directory \/var\/www\/>]\n Options -Indexes -FollowSymLinks -ExecCGI/;P;D'

I've tried putting things inside quotes and square brackets. The command also doesn't seem to like the tabs.

Any ideas would be appreciated.

2 Answers

sed by default operates on each line separately, thus you cannot use \n. If you want to operate on multiple lines, you can use the -z flag, which separates the lines by NUL characters and allows the use of \n.

Also, you don't have to pipe cat's output to sed, since sed can read files by itself.

Furthermore, it is not mandatory to use / as delimiter in your sed command, as sed accepts other delimiters too. Using a different delimiter in your case has the benefit of not having to escape every / using a backslash (\).

So the command you need to run is:

sed -z 's|<Directory /var/www>\n\tOptions Indexes FollowSymLinks|<Directory /var/www>\n\tOptions -Indexes -FollowSymLinks -ExecCGI|' /etc/apache2/apache2.conf

Notice that in the above command I used \t as a tab character. However, not all versions of sed accept \t as a tab character. If the above command does not work for you, you can replace \t by a literal tab in your terminal by pressing Ctrl+V and then hitting Tab, or use another method from this Stack Overflow question: Why is sed not recognizing \t as a tab?

1

You appear to need the search to include the preceding line, but not the replace. So you could search for the first line of the pattern, then use the n command to load the next line, which you can then process in the usual way either using substitute

sed '\:<Directory /var/www>:{ n s/Options Indexes FollowSymLinks/Options -Indexes -FollowSymLinks -ExecCGI/ }' file

or by changing the whole line

sed '\:<Directory /var/www>:{ n c\ Options -Indexes -FollowSymLinks -ExecCGI }' file
1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like