我有一个静态文本块,我需要从夜间创建的文件中删除,将多个文件连接成一个文件。文本横跨6行作为一个块,并有一堆特殊字符,如",比;,和/。我知道我应该能够使用awk
,sed
或perl
,但我无法获得特殊字符的转义正确,要么它出错,要么没有找到块。
代码块始终是这样,分隔行:
</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>
的书尾的行范围,然后d
elete说的范围:
$ 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>