考虑一个文本文件,其中文本行聚集在许多块中,其中每个块至少由一个空行分隔。使用 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>