如何用文件中的单个单词替换多行(就地替换)?

αғs*_*нιη 13 command-line perl sed awk text-processing

我的filename文件内容如下(例如):

My block of line starts from here 
START
First line
second line
third line
END
and end to here for example.
Run Code Online (Sandbox Code Playgroud)

我想,以取代之间的行块START,并END只用一个词,例如用SINGLEWORD。像下面这样:

My block of line starts from here 
SINGLEWORD
and end to here for example.
Run Code Online (Sandbox Code Playgroud)

我可以使用以下命令找到我的行块:

grep -Pzo "START(.|\n)*END" filename
Run Code Online (Sandbox Code Playgroud)

运行上述命令的结果将是这样的:

START
First line
second line
third line
END
Run Code Online (Sandbox Code Playgroud)

然后我使用此命令将所有行合并为一行:

LAST_RESULT | sed -e :a -e '/$/N; s/\n/ /; ta'
Run Code Online (Sandbox Code Playgroud)

然后我会得到这个结果:

START First line second line third line END
Run Code Online (Sandbox Code Playgroud)

通过我的最后一个命令,LAST_RESULTS | sed 's/.*/SINGLEWORD/'我将它们更改为"SINGLEWORD"并得到了这个结果。

SINGLEWORD
Run Code Online (Sandbox Code Playgroud)

现在我想要的是:如何使用此命令(或您的建议命令)并将我的行块替换(就地)为“SINGLEWORD”字样?最终结果将是这个文件:

My block of line starts from here 
SINGLEWORD
and end to here for example.
Run Code Online (Sandbox Code Playgroud)

Syl*_*eau 17

这可以很容易地完成perl

$ perl -i -p0e 's/START.*?END/SINGLEWORD/s' file
$ cat file
My block of line starts from here 
SINGLEWORD
and end to here for example. 
Run Code Online (Sandbox Code Playgroud)

解释

-0 将行分隔符设置为空

-p将给出的脚本-e应用于每一行并打印该行

正则表达式修饰符:

  • /s将字符串视为单行。也就是说,更改.以匹配任何字符,甚至是通常不会匹配的换行符。

为什么?

  • 默认情况下,量化的子模式是“贪婪的”,也就是说,它会尽可能多地匹配(给定一个特定的起始位置),同时仍然允许模式的其余部分匹配。如果您希望它匹配尽可能少的次数,请在量词后跟一个?


c0r*_*0rp 14

我想知道这是否可能没有perlpython和其他人。我使用以下方法找到了这个解决方案sed

$ sed ':a;N;$!ba;s/START.*END/SINGLEWORD/g' filename
Run Code Online (Sandbox Code Playgroud)

解释:

  1. :a 创建一个标签 'a'
  2. N 将下一行追加到模式空间
  3. $! 如果不是最后一行ba 分支(转到)标签 'a'
  4. s 替代, /START.*END/by SINGLEWORD, /g 全局匹配(尽可能多次)

它是在这里找到的。