sed替代品并不像预期的那样工作

问题描述:

我正在执行一个shell脚本,我应该在其中替换文件中的字符串。所以我当然使用sed。该字符串是这样的:sed替代品并不像预期的那样工作

<script src="3.js"></script> 

所以我要把如下做到这一点:

$ sed "s/<\!--replace-->.\*<\!--\/replace-->/<script src=\"3.js\"><\/script>/g" file.html 

但这并不做的伎俩

<!--replace--> 
<script src="1.js"></script> 
<script src="2.js"></script> 
<!--/replace--> 

这应该被替换。我错过了什么?

UPD:从文件中删除\n在这种情况下不是解决方案,因为文件应该是可读的。

的问题与换行符,您可以使用tr改变你的正则表达式匹配换行符,或删除换行符 :

[email protected]:/tmp$ cat s.txt 

<!--replace--> 
<script src="1.js"></script> 
<script src="2.js"></script> 
<!--/replace--> 

[email protected]:/tmp$ tr "\n" " " < s.txt | sed "s#<\!--replace-->.*<\!--/replace-->#<script src="3.js"></script>#g" 

<script src=3.js></script> 

如果你不想删除换行符,您可以:

一个)尝试使用SED溶液作为这里提到: how to tell sed "dot match new line"

b)中使用Perl或Python更换多行的正则表达式,其中s modifi呃,新行将会保留:

[email protected]:/tmp$ cat s.txt 

<!--replace--> 
<script src="1.js"></script> 
<script src="2.js"></script> 
<!--/replace--> 

Dummy content containing 
newlines for test. 

[email protected]:/tmp$ perl -i -pe 'BEGIN{undef $/;} s#<\!--replace-->.*<\!--/replace-->#<script src="3.js"></script>#gsm' s.txt 

[email protected]:/tmp$ cat s.txt 

<script src="3.js"></script> 

Dummy content containing 
newlines for test. 
+0

我不应该从文件中删除换行符,因此这种方式是不是我所需要的。另外AFAIK'。\ *'应该匹配所有字符,包括新行。是对的吗?如果不是,我将如何改变表达式来匹配换行符? – AlexKey

+0

@AlexKey检查我修改后的答案。它解决了您的问题。 – DhruvPathak

+0

好的。链接'a'就像一个魅力。谢谢。 – AlexKey

这可能会为你工作(GNU SED):

sed '/<!--replace-->/!b;:a;$!{N;/<!--\/replace-->/!ba};c\<script src="3.js"></script>' file 

下面是做这件事的一种方法:删除(d)所有线路从包含该行开始<!--replace-->到包含<!--\replace-->的行。但对于块的第一行,请在删除之前插入(i)替换行。

sed '/<!--replace-->/,/<!--\/replace-->/ { 
     /<!--replace-->/ i\<script src="3.js"></script> 
     d  
    }' file 

另一种方式是在图案空间然后替换模式空间附加整个块与更换线(即替换整个块)。

sed '/<!--replace-->/ { 
     :loop 
     N 
     /<!--\/replace-->/ ! b loop 
     c\<script src="3.js"></script> 
    }' file 

详细

  1. 如果行包含<!--replace-->,进入{..}
  2. :loop是一个标签(也就是你可以去标记)
  3. N去下一行并将下一行添加到模式空间。
  4. 如果该行不包含<!--/replace-->,然后去(b牧场)的标签loop
  5. 重复3-4,直到行包含<!--/replace-->。此时,用替换线替换(c hange)图案空间。