shell脚本:在多行上搜索和替换

4 人关注

我正在寻找一种方法,通过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
Reason
Reason
发布于 2011-10-19
3 个回答
Simon C
Simon C
发布于 2013-01-14
已采纳
0 人赞同

如果你只需要匹配完整的行,那么你可以用以下方法完成这项任务 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;
    
我的文件很简单,所以应该可以做到这一点。出于好奇,如果我不能按行计算,是否有任何基本的unix工具可以为我做,或者我需要更强大的东西?
我认为这对 sed 或其他基本UNIX工具来说太难了。 我在 perl 中添加了一个例子。- 我认为这是在不逐行工作时可能的最简单的解决方案。
tripleee
tripleee
发布于 2013-01-14
0 人赞同

sed 就可以做到这一点。以下是最简单的方法;如果你需要从起始定界符之前或结束定界符之后的定界符行中提取东西,那就会比较复杂了。

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

如果你能控制这一点,请修正 "怪异 "的拼写。

scrat.squirrel
scrat.squirrel
发布于 2013-01-14
0 人赞同

另一个解决方案......这有可能在一个单行程序中完成,但使用 perl 正则表达式,我觉得它比 sed or awk (这在多行匹配和替换中是很麻烦的)。