从包含可变数据的文件中删除静态文本块



我有一个静态文本块,我需要从夜间创建的文件中删除,将多个文件连接成一个文件。文本横跨6行作为一个块,并有一堆特殊字符,如",比;,和/。我知道我应该能够使用awk,sedperl,但我无法获得特殊字符的转义正确,要么它出错,要么没有找到块。

代码块始终是这样,分隔行:

</channel>
</rss><?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0">
<channel>
<title><![CDATA[Example]]></title>
<description><![CDATA[Example]]></description>
<link><![CDATA[https://www.example.com/]]></link>

我想更改

</item>
</channel>
</rss><?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0">
<channel>
<title><![CDATA[Example]]></title>
<description><![CDATA[Example]]></description>
<link><![CDATA[https://www.example.com/]]></link>
<item>

</item>
<item>

在通过连接多个流创建的文件中出现8次。

假设:

  • 所有像</channel> ... </link>这样的方块都要移除
  • OP声明文件有8个这样的块
  • 实际数据的格式与OP的示例输入一样(否则,正如Cyrus所提到的,XML/HTML解析器可能更合适)

样本数据:

$ cat sample.dat
</item> keep this line
</channel>
</rss><?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0">
<channel>
<title><![CDATA[Example]]></title>
<description><![CDATA[Example]]></description>
<link><![CDATA[https://www.example.com/]]></link>
<another_item> keep this line
<link><![CDATA[https://www.example.com/KEEP_THIS_LINE]]></link>
</another_item> keep this line
</channel>
</rss><?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0">
<channel>
<title><![CDATA[Example]]></title>
<description><![CDATA[Example]]></description>
<link><![CDATA[https://www.example.com/]]></link>
</one_more_item> keep this line

一个sed的想法是找到具有</channel></link>的书尾的行范围,然后delete说的范围:

$ sed '/</channel>/,/</link>/d' sample.dat
</item> keep this line
<another_item> keep this line
<link><![CDATA[https://www.example.com/KEEP_THIS_LINE]]></link>
</another_item> keep this line
</one_more_item> keep this line

一旦OP验证了答案的准确性,如果目的是用结果覆盖输入文件,则可以添加-i标志。

使用GNU awk支持多字符RS:

$ awk -v RS='^$' -v ORS= 'NR==FNR{rmv=$0; next} s=index($0,rmv){$0=substr($0,1,s-1) substr($0,s+length(rmv))} 1' remove file
</item>
<item>

上面的代码将适用于文件中的任何字符,因为它只是在进行字符串比较,并且它在这些输入文件上运行:

$ head remove file
==> remove <==
</channel>
</rss><?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0">
<channel>
<title><![CDATA[Example]]></title>
<description><![CDATA[Example]]></description>
<link><![CDATA[https://www.example.com/]]></link>
==> file <==
</item>
</channel>
</rss><?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:g="http://base.google.com/ns/1.0" version="2.0">
<channel>
<title><![CDATA[Example]]></title>
<description><![CDATA[Example]]></description>
<link><![CDATA[https://www.example.com/]]></link>
<item>

最新更新