我的文件包含以下行:
Data;moreData;EvenMoreData1;200
Data;moreData;EvenMoreData1;200
Data;moreData;EvenMoreData2;500
Data;moreData;EvenMoreData2;0
Data;moreData;EvenMoreData3;0
Data;moreData;EvenMoreData3;0
基本上每2条线彼此相关。我试图找到最好的方法,只用一个0和它上面或下面的线打印线。所以输出就像。
Data;moreData;EvenMoreData2;500
Data;moreData;EvenMoreData2;0
Data;moreData;EvenMoreData3;0
Data;moreData;EvenMoreData3;0
答案 0 :(得分:7)
$ perl -00 -ne "print if /;0$/m;" < input
0;Data;0;moreData;EvenMoreData2;500
0;Data;0;moreData;EvenMoreData2;0
0;Data;0;moreData;EvenMoreData3;0
0;Data;0;moreData;EvenMoreData3;0
0;Data;0;moreData;EvenMoreData3;0
0;Data;0;moreData;EvenMoreData3;1
-00
打开段落模式,将输入记录分隔符设置为\n\n+
,因此这取决于两条数据行之间的空行。
$ cat input
0;Data;0;moreData;EvenMoreData1;200
0;Data;0;moreData;EvenMoreData1;200
0;Data;0;moreData;EvenMoreData2;500
0;Data;0;moreData;EvenMoreData2;0
0;Data;0;moreData;EvenMoreData3;0
0;Data;0;moreData;EvenMoreData3;0
0;Data;0;moreData;EvenMoreData3;0
0;Data;0;moreData;EvenMoreData3;1
答案 1 :(得分:1)
这可能适合你(GNU sed):
sed -r 'N;N;/;0(\n|$)/p;d' file
答案 2 :(得分:1)
告诉awk记录是用空行(-v RS=
)分隔的,字段是换行符(-F'\n'
),然后检查记录中任何一行末尾的“; 0”: / p>
$ awk -v RS= -v ORS='\n\n' -F'\n' '/;0(\n|$)/' file
Data;moreData;EvenMoreData2;500
Data;moreData;EvenMoreData2;0
Data;moreData;EvenMoreData3;0
Data;moreData;EvenMoreData3;0
将ORS设置为2个换行符(-v ORS='\n\n'
)只是告诉awk在输出记录之间放置一个空行,使其看起来像您的输入格式。如果您不关心这一点,只需不要设置ORS,您就会变得更简单:
$ awk -v RS= -F'\n' '/;0(\n|$)/' file
Data;moreData;EvenMoreData2;500
Data;moreData;EvenMoreData2;0
Data;moreData;EvenMoreData3;0
Data;moreData;EvenMoreData3;0
仅供参考,这将适用于您记录中任意数量的行。
回应评论要求进一步解释:
awk是基于记录的,与基于行的sed不同。 awk的默认记录分隔符是换行符,因此默认情况下awk在行上工作,就像sed一样,但是通过更改记录分隔符(内置RS变量),您可以使用awk处理您喜欢的任何文本块。特别是当您将RS设置为NULL字符串时,awk记录由空行分隔。
因此,在这种特殊情况下,-v RS=
将RS设置为NULL字符串,因此awk将输入处理为3条记录:
记录1)
Data;moreData;EvenMoreData1;200
Data;moreData;EvenMoreData1;200
记录2)
Data;moreData;EvenMoreData2;500
Data;moreData;EvenMoreData2;0
记录3)
Data;moreData;EvenMoreData3;0
Data;moreData;EvenMoreData3;0
dafault的awk将记录分成由白色空间链分隔的字段,但您可以通过设置内置字段分隔符变量FS来改变该行为。在这种情况下,我通过执行-F'\n'
将FS设置为换行符,这意味着上述每条记录都被视为2个字段:
记录1,字段1)
Data;moreData;EvenMoreData1;200
记录1,字段2)
Data;moreData;EvenMoreData1;200
记录2,字段1)
Data;moreData;EvenMoreData2;500
记录2,字段1)
Data;moreData;EvenMoreData2;0
记录3,字段1)
Data;moreData;EvenMoreData3;0
记录3,字段2)
Data;moreData;EvenMoreData3;0
现在我已经到了这一步,我意识到我根本不需要设置FS,因为regexp我最终操作整个记录而不是单个字段,所以这实际上是我所需要的:< / p>
$ awk -v RS= -v ORS='\n\n' '/;0(\n|$)/' file
Data;moreData;EvenMoreData2;500
Data;moreData;EvenMoreData2;0
Data;moreData;EvenMoreData3;0
Data;moreData;EvenMoreData3;0
只是在“\ n”所标记的任何行的末尾(例如,在每条记录的第1行的末尾)或在“由”标识的记录的末尾处查找正则表达式“; 0” $“(例如,在每条记录的第2行末尾,因此/; 0(\ n | $)/将在记录中的任何一行的末尾找到”; 0“。
希望有帮助,并为我在不需要时设置FS的混乱道歉,这是我第一次开始研究这个问题时的神器。
对于高尔夫球手:
$ awk '/;0(\n|$)/' RS= file
Data;moreData;EvenMoreData2;500
Data;moreData;EvenMoreData2;0
Data;moreData;EvenMoreData3;0
Data;moreData;EvenMoreData3;0
答案 3 :(得分:-1)
$ awk -F';' 'NR%3!=0{f=$NF;a=$0;getline;if(f==0||$NF==0)print a"\n"$0"\n"}' file
Data;moreData;EvenMoreData2;500
Data;moreData;EvenMoreData2;0
Data;moreData;EvenMoreData3;0
Data;moreData;EvenMoreData3;0