将大括号与新行匹配

将大括号与新行匹配

尝试使用 . 匹配字符串 + 换行符 + 左大括号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()。这可以避免我们在引用任务中出错。

相关内容