2

I want to insert a block of text after a specific line that starts with the word DocumentRoot.

This is the original text (file named li1023-68.members.linode.com):

<VirtualHost *:80>
    ServerName li1023-68.members.linode.com
    DocumentRoot /srv/www/li1023-68.members.linode.com/public_html/
    ErrorLog /srv/www/li1023-68.members.linode.com/logs/error.log
    CustomLog /srv/www/li1023-68.members.linode.com/logs/access.log combined
</VirtualHost>

This is what I want to achieve:

<VirtualHost *:80>
    ServerName li1023-68.members.linode.com
    DocumentRoot /srv/www/li1023-68.members.linode.com/public_html/
    <Directory /srv/www/$path/public_html>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Order allow,deny
        allow from all
    </Directory>
    ErrorLog /srv/www/li1023-68.members.linode.com/logs/error.log
    CustomLog /srv/www/li1023-68.members.linode.com/logs/access.log combined
</VirtualHost>

I tried doing so with the following code and it doesn't work. $path holds the name of the text that should be modified (ie li1023-68.members.linode.com):

value="<Directory /srv/www/$path/public_html>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
</Directory>"

sed '/DocumentRoot.*$/a $value' /etc/apache2/sites-available/$path
while read line
do
        echo $line
        echo $line | grep -q "DocumentRoot"
        [ $? -eq 0 ] && echo "$value"
done < $path

What am I missing?

1 Answer 1

2

The single quotes prevent the shell from expanding $value, and you need to use sed's s (substitute) command:

sed -i "s!DocumentRoot.*!&\n$value!" /etc/apache2/sites-available/$path

The -i argument tells sed to do in-place substitution; that is, change the file without sending the output to stdout, and you don't need the $ at the end of the search string.

But sed will see the first newline in $value and assume it terminates the command, which is not what you want. Replace the newlines in $value with \n like this:

value="<Directory /srv/www/$path/public_html>\nOptions Indexes FollowSymLinks MultiViews\n..."

[Edit: Note, also that it's customary to delimit the pattern and replacement with slashes, but then sed will assume the slashes in $value are delimiters! So we can use exclamation points (or any other unused character) instead.]

Then you won't need the loop at all.

If you use the loop instead (you don't need both), remember to specify the entire filename:

done < /etc/apache2/sites-available/$path
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks adam for the answer but I'm getting an error "sed: -e expression #1, char 33: unknown option to `s'"
Hah! I think sed is seeing the slashes in the Directory name and thinking they're part of the command. I'll update my answer; Sorry.
The loop seems to work for me. What error are you seeing?
It worked! what is the equivalent for indent/tab like '\n' is for new line?
\t is a tab. See tldp.org/LDP/abs/html/escapingsection.html or use man bash from your command prompt.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.