如何使用bash在特定行之后插入文本?

时间:2015-09-27 19:32:20

标签: bash sed

我想在以DocumentRoot开头的特定行之后插入一个文本块。

这是原始文本(名为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>

这就是我想要实现的目标:

<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>

我尝试使用以下代码执行此操作,但它无法正常工作。 $path包含应修改的文本的名称(即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

我错过了什么?

1 个答案:

答案 0 :(得分:2)

单引号可防止shell展开$value,您需要使用sed的s(替换)命令:

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

-i参数告诉sed进行就地替换;也就是说,更改文件而不将输出发送到标准输出,并且您不需要搜索字符串末尾的$

但是sed会看到$value中的第一个换行符并假设它终止了命令,这不是你想要的。将$value中的换行符替换为\n,如下所示:

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

[编辑:注意,也是按照惯例来划分模式并用斜线替换,但是sed将假设$value中的斜杠是分隔符!所以我们可以使用感叹号(或任何其他未使用的字符)代替。]

然后你根本不需要循环。

如果您使用循环(您不需要两者),请记住指定整个文件名:

done < /etc/apache2/sites-available/$path