簡體   English   中英

使用香草Ubuntu,一個用於搜索和替換/取消注釋代碼塊的腳本?

[英]Using vanilla Ubuntu, a script to search and replace/uncomment a block of code?

我正在嘗試自動化開發環境在Ubuntu 14.04中的安裝,其中一部分要求我取消注釋Nginx vHost配置的代碼塊:

    #location ~ \.php$ {
    #       fastcgi_split_path_info ^(.+\.php)(/.+)$;
    #       # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
    #
    #       # With php5-cgi alone:
    #       fastcgi_pass 127.0.0.1:9000;
    #       # With php5-fpm:
    #       fastcgi_pass unix:/var/run/php5-fpm.sock;
    #       fastcgi_index index.php;
    #       include fastcgi_params;
    #}

我試過sed:

sed -i "s/#location ~ \.php$ {
        #       fastcgi_split_path_info ^(.+\.php)(/.+)$;
        #       # NOTE: You should have \"cgi.fix_pathinfo = 0;\" in php.ini
        #
        #       # With php5-cgi alone:
        #       fastcgi_pass 127.0.0.1:9000;
        #       # With php5-fpm:
        #       fastcgi_pass unix:/var/run/php5-fpm.sock;
        #       fastcgi_index index.php;
        #       include fastcgi_params;
        #}/location ~ \.php$ {
          fastcgi_split_path_info ^(.+\.php)(\/.+)$;
          # NOTE: You should have \"cgi.fix_pathinfo = 0;\" in php.ini

          # With php5-cgi alone:
          fastcgi_pass 127.0.0.1:9000;
          # With php5-fpm:
          fastcgi_pass unix:\/var\/run\/php5-fpm.sock;
          fastcgi_index index.php;
          include fastcgi_params;
        }/g" /etc/nginx/sites-available/nginx.dev;

但這返回:

sed: -e expression #1, char 22: unterminated `s' command

我認為與語法錯誤有關,我試圖轉義/"字符,但我認為這根本不夠/正確。

我發現了這個: https : //unix.stackexchange.com/a/26289/138115

這表明perl可能是一個很好的解決方案,因為它是隨Ubuntu一起安裝的,所以我嘗試了它:

perl -0777 -i.original -pe 's/#location ~ \.php$ {\n        #       fastcgi_split_path_info ^(.+\.php)(\/.+)$;\n        #       # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini\n        #\n        #       # With php5-cgi alone:\n        #       fastcgi_pass 127.0.0.1:9000;\n        #       # With php5-fpm:\n        #       fastcgi_pass unix:\/var\/run\/php5-fpm.sock;\n        #       fastcgi_index index.php;\n        #       include fastcgi_params;\n        #}/slocation ~ \.php$ {\n  fastcgi_split_path_info ^(.+\.php)(\/.+)$;\n  NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini\n  With php5-cgi alone:\n  fastcgi_pass 127.0.0.1:9000;\n  With php5-fpm:\n  fastcgi_pass unix:\/var\/run\/php5-fpm.sock;\n  fastcgi_index index.php;\n  include fastcgi_params;\n}/igs' /etc/nginx/sites-available/nginx.dev;

但這會帶來很多語法錯誤:

syntax error at -e line 1, near "(."
Unknown regexp modifier "/v" at -e line 1, within string
Unknown regexp modifier "/r" at -e line 1, within string
Unknown regexp modifier "/h" at -e line 1, within string
Unknown regexp modifier "/5" at -e line 1, within string
Not enough arguments for index at -e line 1, near "index."
syntax error at -e line 1, near "n}"
Execution of -e aborted due to compilation errors.

以前,我已經針對各種環境編寫了許多這樣的腳本,但是我一直試圖避免替換多行文本,因為我一直無法正確處理。 今天,我已經花費了3個小時,但是對於如何解決這個問題我仍然沒有真正的了解。 如果有人可以分享一些意見/見解以及如何實現,那么將不勝感激,謝謝!

編輯1:

用方括號簡單轉義:

#!/bin/bash
#/etc/nginx/sites-available/test.sh
file=$(<default.file);
search=$(<nginx_search.txt);
replace=$(<nginx_replace.txt);
$file =~ s[$search][$replace]g;
echo "$file" > "/etc/nginx/sites-available/test.file";
# Outputs notice: ./test.sh: line 6: #: command not found

test.file已創建,但包含default.file的原始值,但未進行任何修改。

在perl中進行測試后,我收到:

syntax error at ./perl.perl line 6, near "(."
Unknown regexp modifier "/v" at ./perl.perl line 6, within string
Unknown regexp modifier "/r" at ./perl.perl line 6, within string
Unknown regexp modifier "/h" at ./perl.perl line 6, within string
Unknown regexp modifier "/5" at ./perl.perl line 6, within string
syntax error at ./perl.perl line 9, near ";
}"
Execution of ./perl.perl aborted due to compilation errors.

第6行顯示:

#       # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini

注意-您提到(和標記) perl 以下是從perl角度來看。 其中一些可能適用於常規外殼,但是我不能確切地說出什么。 perl確實支持一些基本POSIX規范之外的正則表達式。

這樣的模式的問題在於,模式中包含定界符。 您的首字母縮寫失敗,因為它將處理此斜杠:

    #       fastcgi_pass unix:/var/run/php5-fpm.sock;

作為圖案中的“分割點”。 您可以通過轉義定界符來解決此問題,但實際上更好的技巧是-使用其他地方不存在的定界符。 在上面,我建議您可以使用方括號:

my $str = "some fish"; 
$str =~ s[some][more]g;

print $str;

盡管作為替代方案,但是您可以使用范圍運算符 ,如果它在兩個指定的定界符之內,則測試為“ true”:

while ( <> ) {
   if ( m|\#location.*php\$ \{| .. m|^\s*#\}| ) {
       s/#//;
   }
   print ;
}

例如:

#!/usr/bin/perl
use strict;
use warnings;


while ( <DATA> ) {
   if ( m|\#location.*php\$ \{| .. m|^\s*#\}| ) {
       #note - no g modifier, so we only do the first per line
       s/#//;
   }
   print ;
}

__DATA__
# Some stuff
we don't care about this line
#and this shouldn't be changed

#but after this point, it should be!

   #location ~ \.php$ {
    #       fastcgi_split_path_info ^(.+\.php)(/.+)$;
    #       # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
    #
    #       # With php5-cgi alone:
    #       fastcgi_pass 127.0.0.1:9000;
    #       # With php5-fpm:
    #       fastcgi_pass unix:/var/run/php5-fpm.sock;
    #       fastcgi_index index.php;
    #       include fastcgi_params;
    #}


# and now we stop, and leave this bit alone. 

    more stuff; 
    here; 
    # and another comment line

如果您在兩個定界符之間(上述位置php和“ squiggly方括號”),則有條件地應用轉換。

您可以對此進行單行驗證:

perl -ne 'if ( m|\#location.*php\$ \{| .. m|^\s*#\}| ) { s/#//g; } print' myfile

(如果您想就地編輯,請添加-i )。

我認為,這些長字符串替換總是挑剔的,通常最好嘗試避免盡可能多地處理內容。 我想到了這個,它只是捕獲字符串,刪除第一個#並重新打印該行:

use strict;
use warnings;

my $search = q|#location ~ \.php$ {
    #       fastcgi_split_path_info ^(.+\.php)(/.+)$;
    #       # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
    #
    #       # With php5-cgi alone:
    #       fastcgi_pass 127.0.0.1:9000;
    #       # With php5-fpm:
    #       fastcgi_pass unix:/var/run/php5-fpm.sock;
    #       fastcgi_index index.php;
    #       include fastcgi_params;
    #}
|;

local $/;   # slurp the file
while (<DATA>) {
    s|(\Q$search\E)| my $x = $1; $x =~ s/^\s*#//mg; $x; |e;
    print;
}    
__DATA__
    # stuff
    #location ~ \.php$ {
    #       fastcgi_split_path_info ^(.+\.php)(/.+)$;
    #       # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
    #
    #       # With php5-cgi alone:
    #       fastcgi_pass 127.0.0.1:9000;
    #       # With php5-fpm:
    #       fastcgi_pass unix:/var/run/php5-fpm.sock;
    #       fastcgi_index index.php;
    #       include fastcgi_params;
    #}
    #comment

請注意,使用\\Q ... \\E可以避免字符串中的正則表達式元字符弄亂您。

使用這種方法,如果需要的話,從技術上講,您還應該能夠從文件中讀取搜索字符串。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM