2017-03-14 71 views
0

我將一行Perl代碼添加到Makefile中,該Makefile在httpd.conf中搜索類似於以下塊的內容,並將AllowOverride替換爲「All」的「None」。Perl多行正則表達式替換捕獲組

<Directory "/var/www/html"> 
    # 
    # Possible values for the Options directive are "None", "All", 
    # or any combination of: 
    # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews 
    # 
    # Note that "MultiViews" must be named *explicitly* --- "Options All" 
    # doesn't give it to you. 
    # 
    # The Options directive is both complicated and important. Please see 
    # http://httpd.apache.org/docs/2.4/mod/core.html#options 
    # for more information. 
    # 
    Options Indexes FollowSymLinks 

    # 
    # AllowOverride controls what directives may be placed in .htaccess files. 
    # It can be "All", "None", or any combination of the keywords: 
    # Options FileInfo AuthConfig Limit 
    # 
    AllowOverride None 

    # 
    # Controls who can get stuff from this server. 
    # 
    Require all granted 
</Directory> 

我想在命令行中運行的代碼如下:

sudo perl -p -i -e 's/(<Directory "\/var\/www\/html">.*AllowOverride)(None)/\1 All/' httpd.conf 

但我無法得到它的工作。我使用兩個捕獲組來保持第一組相同並替換第二組。

任何幫助,非常感謝。

編輯:此解決它

sudo perl -0777 -p -i -e 's/(<Directory \"\/var\/www\/html\">.*?AllowOverride) (None)/\1 All/s' httpd.conf 
+1

「-p」標誌默認只讀取一行。嘗試通過添加'-0777'來嘗試sl more多行。另請參見[如何在Perl RegEx中替換多個任意字符(包括換行符)](http://stackoverflow.com/q/36533282/2173773) –

+1

另外,請確保使用非貪婪的'。*?'否則它將一路匹配到最後一個'AllowOverride'。使用'$ 1',而不是'\ 1'或'\ K'(_positive lookbehind_的一種形式)。 – zdim

+0

解決了這個問題:sudo perl -0777 -p -i -e's /(。*?AllowOverride)(None)/ \ 1 All/s' httpd.conf – lorenzo

回答

3

一般來說,解析和修改任何嵌套的正則表達式迅速變得複雜容易出錯。如果可以,請使用完整的解析器。

幸運的是有一個用於讀取和修改Apache配置文件,Apache::Admin::Config。起初有點奇怪,所以這裏有一個例子。

#!/usr/bin/env perl 

use strict; 
use warnings; 
use v5.10; 

use Apache::Admin::Config; 

# Load and parse the config file. 
my $config = Apache::Admin::Config->new(shift) 
    or die $Apache::Admin::Config::ERROR; 

# Find the <Directory "/var/www/html"> section 
# NOTE: This is a literal match, /var/www/html is different from "/var/www/html". 
my $section = $config->section(
    "Directory", 
    -value => q["/var/www/html"] 
); 

# Find the AllowOverride directive inside that section. 
my $directive = $section->directive("AllowOverride"); 

# Change it to All. 
$directive->set_value("All"); 

# Save your changes. 
$config->save; 

您正在一次鑽一層結構。首先找到該部分,然後找到該部分中的指令。

你可以在循環中做到這一點。例如,查找所有目錄段...

for my $section ($config->section("Directory")) { 
    ... 
}