此 awk 单行代码适用于您的示例:
awk -v RS="" '{gsub(/\n/,"\x99")}NR==FNR{t=$0;next}{gsub(t,"");gsub(/\x99/,"\n");print}' bar foo
不完全相同的输出(空行),但你明白了。请参阅示例下方的简短说明。
请参见下面的示例:
kent$ head foo bar
==> foo <==
<ul>
<li>
<p>something</p>
</li>
<li>
<p>something else</p>
</li>
</ul>
==> bar <==
<li>
<p>something</p>
</li>
kent$ awk -v RS="" '{gsub(/\n/,"\x99")}NR==FNR{t=$0;next}{gsub(t,"");gsub(/\x99/,"\n");print}' bar foo
<ul>
<li>
<p>something else</p>
</li>
</ul>
添加简短说明
基本思想是,用不可见的字符替换换行符(在我使用的示例中\x99
),然后我们有两个单行字符串。我们可以进行匹配和替换。在我们处理完字符串后,将所有字符串全部替换\x99
回换行符以获取原始格式。这个想法也适用于 sed,但有点复杂,你必须制作一个标签并使用模式/保持空间......
在我刚刚使用的示例中RS=""
(我有点懒)。您可以使用sprintf
函数来构建单行字符串,它会更通用,因为您的两个真实文件都可能有空行。(但是你的例子没有)
关键是看不见的字符替换部分。
祝你好运!