只需告诉 awk 记录由空行 ( -v RS=
) 分隔,字段由换行符 ( -F'\n'
) 分隔,然后检查记录中任何行末尾的“;0”:
$ 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
awk by dafault 将记录分成由空格链分隔的字段,但您可以通过设置内置的字段分隔符变量 FS 来更改该行为。在这种情况下,我将 FS 设置为换行符,-F'\n'
这意味着上述每个记录都被视为 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,因为我最终使用的正则表达式对整个记录而不是单个字段进行操作,所以这实际上就是我所需要的:
$ 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