输入由许多由空行分隔的行块构成 我需要在打印剩余的> 1行块时去除单行块
示例输入:
block1
block2
block2
block2
block3
block4
block4
block5
block6
block6
预期输出:
block2
block2
block2
block4
block4
block6
block6
答案 0 :(得分:1)
您可以使用awk
记录分隔符:
awk '$2!=""{print $0"\n"}' RS='' file
答案 1 :(得分:1)
awk可以很容易地通过重新定义字段分隔符和记录分隔符来实现。
首先,重要的是要认识到awk的两个最重要的概念是记录和字段。
通过 record 读取通过各种方式(stdin
或getline
)输入到awk的输入 record ,其中每个记录都分开由RS
定义的记录分隔符。由于RS
在默认情况下是\n
,因此记录实际上是一行,因此awk默认会逐行处理文件。
读取记录/行时,awk会将记录拆分为各个字段,其中每个字段都由字段分隔符FS
(可以是正则表达式)分隔。默认情况下,字段分隔符FS
设置为任何FS
,则字段将不同。
一种特殊的记录分隔符是空的RS=""
,因为它同时定义了RS
和FS
如果
RS
为null,则记录由由加上一个或多个空行组成的序列分隔,开头或结尾的空行在输入的开始或结尾处均不会导致空记录,并且无论 FS
的值是什么,都应始终是字段分隔符。
因此您可以执行以下操作:
awk 'BEGIN{RS="";ORS="\n\n"}(NF>1)' file
答案 2 :(得分:1)
在
中sed
-
(根据评论中的建议进行编辑,非常感谢)-
sed -n '
/[^[:blank:]]/ H;
/^[[:blank:]]*$/ { x; /.*[^[:blank:]].*\n.*[^[:blank:]].*/ { p; d; } }
$ { x; /.*[^[:blank:]].*\n.*[^[:blank:]].*/ { p; n; } }
' infile
block2
block2
block2
block4
block4
block6
block6
/[^[:blank:]]/ H;
说
如果有非空白,请将图案附加到保留空间。 (您可以详细说明该检查以使其更强大-我将使用example-simple。)
/^ *$/ { x; /.*[^ ].*\n.*[^ ].*/ { p; d; } }
说
/^[[:blank:]]*$/ {
空白行,
x
交换模式并保留空格;然后
/.*[^[:blank:]].*\n.*[^[:blank:]].*/ {
IF 有换行符分隔的内容行,其中包含非空格
p; d;
打印并删除(这将触发下一次读取到模式空间中)。
} }
关闭两个打开的条件。
最后行中的
$ { x; /.*[^[:blank:]].*\n.*[^[:blank:]].*/ { p; n; } }
说
$ {
,
x
交换模式并保留空格;然后
/.*[^[:blank:]].*\n.*[^[:blank:]].*/ {
IF 有换行符分隔的内容行,其中包含非空格
p; n;
打印并继续,这将结束程序。
} }
关闭两个打开的条件。
就是这样。
sed
并不是我理想中的 “完全转换”,但确实提供了相当复杂的逻辑处理的规定。希望这会有所帮助。
答案 3 :(得分:0)
请您尝试以下。
awk '
NF{
++count
val=val?val ORS $0:$0
}
!NF && count>1{
print val ORS $0
val=count=""
}
!NF && count<=1{
val=count=""
}
END{
if(val && count){
print val
}
}' Input_file
答案 4 :(得分:0)
使用Perl单线版
> cat blocks.txt
block1
block2
block2
block2
block3
block4
block4
block5
block6
block6
> perl -ne ' BEGIN { $/="\n\n" } { print if /((.+?)\n)\1{1,}/ } ' blocks.txt
block2
block2
block2
block4
block4
block6
block6
>
如果文件可以容纳到内存中,则是另一个变种
> perl -0777 -ne ' { while(/((.+?)\n)\1{1,}\n?/g) { print "$&" } } ' blocks.txt
block2
block2
block2
block4
block4
block6
block6
>