shell 脚本:多行搜索和替换

问题描述 投票:0回答:3

我正在寻找一种通过 shell 脚本搜索和替换多行的方法。这就是我正在尝试做的:

source:
[stuff before]
<!--WIERD_SPECIAL_COMMENT_BEGIN-->
  [stuff here, possibly multiple lines.
<!--WIERD_SPECIAL_COMMENT_END-->
[stuff after]    

target:
[stuff before]
[new content]
[stuff after]

简而言之,我想删除评论以及评论之间的所有内容,并替换为一些新内容。基本上,我想在多行上执行一个简单的 sed 命令,如果可能的话,只使用一些基本的 *nix 工具,不需要额外的脚本语言。

regex linux unix replace
3个回答
1
投票

如果您只需要匹配完整的行,那么您可以使用以下命令来完成此任务

awk
。 比如:

    awk -v NEWTEXT=foo 'BEGIN{n=0} /COMMENT_BEGIN/ {n=1} {if (n==0) {print $0}} /COMMENT_END/ {print NEWTEXT; n=0}' < myfile.txt

如果文件格式不太好,请添加注释 与您要保留或删除的文本相同的行,然后我 将使用

perl
,将整个文件读入单个字符串, 对该字符串进行正则表达式匹配和替换,然后将新字符串写入 一个新文件。 这并不那么简单,您需要编写一个
perl
脚本来完成这项工作。 比如:

#!/usr/bin/perl
$newtext = "foo\nbar";
$/ = '';  # no input separator so whole file is read.
$s = <>;  # read whole file from stdin
$startPattern = quotemeta('<!--WIERD_SPECIAL_COMMENT_BEGIN-->');
$endPattern = quotemeta('<!--WIERD_SPECIAL_COMMENT_END-->');
$pattern = $startPattern . '.+' . $endPattern;
$s =~ s/$pattern/$newtext/sg;
print $s;

1
投票

sed
这样做就很好了。下面就很简单了;如果您需要从开始定界符之前或结束定界符之后的定界符行中提取内容,那会更复杂一些。

sed '/<!--WIERD_SPECIAL_COMMENT_BEGIN-->/,/<!--WIERD_SPECIAL_COMMENT_END-->/d' input >output

如果你对此有任何控制权,请修正“weird”的拼写。


1
投票

另一种解决方案...这可以在一行中完成,但是使用 perl 正则表达式,我发现它比 sedawk (对于多行匹配来说很麻烦)更容易使用并更换):

perl -0 -i -pe 's/<!--WEIRD_SPECIAL_COMMENT_BEGIN-->[\s\S]*<!--WEIRD_SPECIAL_COMMENT_END-->/your new content here/gim' yourfile1.txt

请注意,这会将文件替换为新的、更改的内容。

注意:如果您不理解正则表达式,请用谷歌搜索。如果你不知道 Perl 语法,请谷歌一下。

© www.soinside.com 2019 - 2024. All rights reserved.