尝试使用 . 匹配字符串 + 换行符 + 左大括号sed
。
sub feature_get_web_php_mode
{
my ($d) = @_;
my $server = &find_domain_server($d);
成为这样
sub feature_get_web_php_mode
{
return 'fcgid';
my ($d) = @_;
my $server = &find_domain_server($d);
我的表达式正则表达式看起来像这样:s|sub feature_get_web_php_mode\n{|CHANGE_CODE|
但它不起作用。
试图找到左大括号在开始时不匹配的原因,但没有任何线索。
先感谢您。
答案1
试图找到左大括号在开始时不匹配的原因,但没有任何线索。
默认情况下,sed
一次操作一行,因此您读取的行不能包含\n
在其中。由于您使用的是 GNU sed
,因此 if 提供了-z
允许您操作以 NUL ( \0
) 字符分隔的文本块的选项。您唯一需要更改命令的是添加该-z
选项:
sed -z "s|sub feature_get_web_php_mode\n{\n|&return 'fcgid';\n|"
请注意,我希望您的输入文件中不存在 NUL 字符(它看起来像常规文本文件),因此它将完全加载到内存中,以便sed
可以处理它(这可能是无害的,因为这是一个程序文件)。
如果您的文件确实太大,您可以尝试这个替代版本:
sed "/^sub feature_get_web_php_mode\$/ { N; s|\n{|&\nreturn 'fcgid';|; }"
郑重声明,以下版本严格符合 Posix:
sed "/^sub feature_get_web_php_mode\$/ { N; s|\n{|&\\
return 'fcgid';|; }"
答案2
更改文本
sub feature_get_web_php_mode
{
my ($d) = @_;
my $server = &find_domain_server($d);
进入
sub feature_get_web_php_mode
{
return 'fcgid';
my ($d) = @_;
my $server = &find_domain_server($d);
通过匹配sub feature_get_web_php_mode
下一行后面的字符串{
,然后插入新行
return 'fcgid';
你必须做
sed '/^sub feature_get_web_php_mode$/ { N; /\n{$/ a\
'"return 'fcgid'"';
}' file
这将准确定位到 的行sub feature_get_web_php_mode
。一旦找到,就会使用该N
命令将下一行附加到输入缓冲区,并在其间添加换行符。接下来,如果模式\n{$
匹配,则读入的行N
是单个字符{
,并且可以添加新行。
新行将通过命令添加a
。该a
命令看起来像
a\
text to be added
由于我们要添加的文本包含单引号,并且由于我们的sed
脚本是用单引号引起来的,因此我们暂时突破sed
程序的单引号,将文本添加到双引号中。
或者,用双引号引用整个表达式(记住在此处转义\
后面的内容a
):
sed "/^sub feature_get_web_php_mode$/ { N; /\n{$/ a\\
return 'fcgid';
}" file
使用 GNU sed
,你可以这样做:
sed -e '/^sub feature_get_web_php_mode$/ { N; /\n{$/ a \' -e "return 'fcgid';" -e '}' file
其他sed
实现也可能能够运行它,但可能不会在添加的行之后插入换行符。
另一种方法是准备补丁文件:
diff -u file.old file.new >file.patch
这可能会导致补丁文件看起来像
--- file.old Wed May 12 22:44:00 2021
+++ file.new Wed May 12 22:44:15 2021
@@ -1,4 +1,5 @@
sub feature_get_web_php_mode
{
+return 'fcgid';
my ($d) = @_;
my $server = &find_domain_server($d);
要将其应用到某个文件,请创建一个包含更改的新文件:
patch -o somefile.patched somefile <file.patch
如果没有-o somefile.patch
,更改将直接应用到somefile
并将原始文件备份为somefile.orig
.
答案3
您似乎想要编辑代码subroutine
中a 的定义perl
。
仅供参考,Perl
子例程可以像变量一样定义/重新定义。
为此,请将以下三个步骤放入您的代码中以实现您想要的更改:
{
no warnings q(redefine);
undef &feature_get_php_mode;
*feature_get_php_mode = sub { return q(fcgid); };
}
但如果您必须编辑代码,那么您可以执行以下操作:
sed -e '
/^sub feature_get_web_php_mode$/!b
n;/^{$/G
s/\n/&return q(fcgid);/
' file
笔记:-
- 我使用了 Perlish 的方式通过运算符使用单引号字符串
q()
。这可以避免我们在引用任务中出错。