Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex shell脚本:在多行上搜索和替换_Regex_Linux_Unix_Replace - Fatal编程技术网

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

Regex shell脚本:在多行上搜索和替换,regex,linux,unix,replace,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]

我正在寻找一种通过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工具,不使用其他脚本语言。

如果您只需要匹配完整的行,那么您可以使用
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
#!/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;

sed
做得很好。以下内容非常简单;如果需要从开始分隔符之前或结束分隔符之后的分隔符行中提取内容,这将有点复杂

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

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

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

perl-0-i-pe's/[\s\s]*/your新内容/gim'yourfile1.txt

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

我的文件非常简单,因此应该可以做到这一点。出于好奇,如果我不能按行操作,是否有任何基本的unix工具可以为我做到这一点,或者我需要更强大的工具?我认为这对于
sed
或其他基本的unix工具来说太难了我在
perl
中添加了一个示例-我认为这是不逐行工作时最简单的解决方案。
perl -0 -i -pe 's/<!--WIERD_SPECIAL_COMMENT_BEGIN-->[\s\S]*<!--WIERD_SPECIAL_COMMENT_END-->/your new content here/gim' yourfile1.txt