shell脚本:搜索并替换多行

时间:2011-10-19 11:17:31

标签: regex linux unix replace

我正在寻找一种通过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工具,不需要额外的脚本语言。

3 个答案:

答案 0 :(得分: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 :(得分:1)

sed这样做很好。以下内容非常简单;如果你需要在开始分隔符之前或结束分隔符之后从分隔符行中提取东西,那将会更加复杂。

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

如果您对此有任何控制权,请修改“怪异”的拼写。

答案 2 :(得分:0)

另一个解决方案......这可以在单行中完成,但使用 perl 正则表达式,我发现它比 sed 更容易使用 awk (多行匹配和替换很麻烦):

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

请注意,这将使用新的更改内容替换该文件。