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 FollowSymLinksTo this:
<Directory /var/www> Options -Indexes -FollowSymLinks -ExecCGISince 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.confNotice 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?
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/ }' fileor by changing the whole line
sed '\:<Directory /var/www>:{ n c\ Options -Indexes -FollowSymLinks -ExecCGI }' file 1