我想AllowOverride None
从有路径的组中进行替换/var/www/
。我正在使用 sed 来执行此操作,但它会替换所有匹配项。
Apache2.conf在运行脚本之前
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>
<Directory /usr/share>
AllowOverride None
Require all granted
</Directory>
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
Apache2.conf运行脚本后
<Directory />
Options FollowSymLinks
AllowOverride All
Require all denied
</Directory>
<Directory /usr/share>
AllowOverride All
Require all granted
</Directory>
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
脚本文件
#!/bin/bash
sed "s/AllowOverride None/AllowOverride All/g" apache2.conf
我的问题是:我如何告诉 sed 替换它的位置/var/www/
?
答案1
您可以使用以下 Perl oneliner 来实现此目的:
perl -0777 -pe 's{(<Directory\s/var/www/.*?AllowOverride\s)None(.*?</Directory>)}{$1All$2}gs' /tmp/file
这里-0777
flag 将行分隔符更改为 undef,因此 perl 会将文件作为一行读取(这对于大文件可能是一个问题)。
-p
循环文件行并打印它们,
-e
运行脚本,
/tmp/file
您的配置文件
s{(<Directory\s/var/www/.*?AllowOverride\s)None(.*?</Directory>)}{$1All$2}gs
是与 /var/www 匹配目录节的 2 部分的正则表达式,并且基本上将 None 替换为 All。请注意,在 Perl 中,您几乎可以使用任何符号作为正则表达式分隔符,在本例中我使用{}
而不是//
.
答案2
一种方法sed
是:
sed -E '/<Directory \/var\/www\/>/,/<\/Directory>/{
s/AllowOverride None/AllowOverride All/; }' infile
这更新/更改了AllowOverride None
到AllowOverride All
仅当介于两者之间时<Directory /var/www/>
&</Directory>
(我们用反斜杠转义斜杠,这是因为斜杠对于 sed 命令来说是特殊字符)。