我正在尝试在开发环境的 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;
虽然作为替代方案 - 您可以使用 range operator如果它在两个指定的分隔符内,则测试为“真”:
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 和“关闭波浪括号”),这有条件地应用转换。
你可以单线化这个:
perl -ne 'if ( m|\#location.*php\$ \{| .. m|^\s*#\}| ) { s/#//g; } print' myfile
(如果您想就地编辑,请添加
-i
)。
关于bash - 使用 vanilla Ubuntu,一个用于搜索和替换/取消注释代码块的脚本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33078696/