shell脚本:多行搜索和替换

发布于 2024-12-10 21:08:15 字数 386 浏览 0 评论 0原文

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

I'm looking for a way to search and replace over multiple lines through a shell script. This is what I'm trying to do:

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]

In short, I want to delete the comments and everything between them and replace with some new content. Basically, I want to do a simple sed command over multiple lines, and if possible just using some basic *nix tools, no additional scripting language.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我喜欢麦丽素 2024-12-17 21:08:15

如果您只需要匹配完整的行,那么您可以使用以下命令来完成此任务
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;

If you only need to match complete lines then you can do this task with
awk. Something like:

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

If the file is not so well formatted, with comments on
the same line as text you want to keep or remove, then I
would use perl, read the entire file into a single string,
do a regular expression match and replace on that string, then write the new string to
a new file. This is not so simple and you need to write a perl script to do the work.
Something like:

#!/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;
情绪操控生活 2024-12-17 21:08:15

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

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

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

sed does this just fine. The following is as simple as it gets; if you need to extract stuff from the delimiter line before the start delimiter or after the end delimiter, that's going to be a little more complex.

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

If you have any control over this, fix the spelling of "weird".

后来的我们 2024-12-17 21:08:15

另一种解决方案...这可以在一行中完成,但是使用 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

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

another solution... this is possible to be done in a one-liner, but using perl regular expressions, which I find easier to work with than sed or awk (which are cumbersome with multi-line match and replace):

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

please note that this will replace the file with the new, changed content.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文