删除括号之间的文本,但不要超过空行

删除括号之间的文本,但不要超过空行

考虑一个文本文件,其中文本行聚集在许多块中,其中每个块至少由一个空行分隔。使用 Bash 语句,如何删除或<中的所有文本?>\n\n

换句话说:删除每对<和之间的所有内容>。如果 a<没有结束>,则删除直到块末尾(空行)的所有内容,但是永远不能删除块外!

从概念上讲,为了安全起见,我应该在解析之前将块物理分离为列表中的对象,还是只要您知道自己在做什么,这就是一个直接的线性文本解析工作吗?

示例文本:

This is the first
block of text.
                             <-- empty line
<delete me>
This is the second block.
<delete
here>
<delete this, but
                             <-- empty line
do not delete this>
<delete this too>
Third block here.

(more blocks)

结果应该是:

This is the first
block of text.
                             <-- empty line
This is the second block.
                             <-- empty line
do not delete this>
Third block here.

答案1

尝试 awk 的段落模式:

$ awk -v RS= -v ORS='\n\n' '{gsub(/<[^>]+>?\n?/, "")}1' ip.txt 
This is the first
block of text.

This is the second block.


do not delete this>
Third block here.
  • -v RS=这将导致一个或多个连续的空行被用作输入记录分隔符
  • -v ORS='\n\n'将输出记录分隔符设置为两个换行符
  • gsub(/<[^>]+>?\n?/, "")删除<后跟非>字符,后跟可选>字符和换行符
  • 1打印输入记录内容的惯用方法


同样的事情与perl

perl -00 -lpe 'BEGIN{$\="\n\n"} s/<[^>]+>?\n?//g' ip.txt

答案2

GNUAwk解决方案:

awk -v RS='[<>]' '/\n\n/{ sub(/^[^\n]+\n/, ""); print $0 RT }' file
  • RS='[<>]'- 将<>视为记录分隔符
  • /\n\n/- 如果当前记录包含 2 个换行符:
    • sub(/^[^\n]+\n/, "")- 删除所有内容,直到第一个换行符(包括)
    • print $0 RT- 打印当前记录,后跟RT(即>
    • RT- 记录终结者。Gawk设置RT为与 指定的字符或正则表达式匹配的输入文本RS

输出:

<empty line>   
don't delete this>

相关内容