【发布时间】:2020-11-18 09:40:23
【问题描述】:
我正在使用 GNU Awk 4.1.3。我要处理这个文件:
$$$$
1
1
$$$$
2
2
$$$$
3
3
$$$$
1
clave
2
$$$$
5
5
$$$$
当给定的块中包含文本“clave”时,打印“$$$$”和下一个“$$$$”之间的行块。也就是说,对于给定的示例,我想要这个输出:
1
clave
2
我的解决方案是将record separator RS 设置为字符串“$$$$”。因为是特殊字符,所以需要转义,所以最后变成RS='\\$\\$\\$\\$':
awk -v RS='\\$\\$\\$\\$' '/clave/' file
这样做的问题是结果在块之前和之后包含一个新行:
$ awk -v RS='\\$\\$\\$\\$' '/clave/' file
1
clave
2
这是因为“$$$$”的末尾和“1”之间有一个新行,“2”和下一个“$$$$”之间也有一个新行。
为了避免这种情况,我在记录分隔符的两端添加了新行,所以它变成了RS='<strong>\n</strong>\$\$\$\$<strong>\n</strong>'。效果很好:
$ awk -v RS='\n\\$\\$\\$\\$\n' '/clave/' file
# ^^^ ^^
1
clave
2
但是,这变得相当复杂,我想知道在记录分隔符中包含新行是否会产生一些我不知道的副作用。
为此,我想知道:如何设置记录分隔符使其包含新行?我的方法是否有效,还是因为我的方法有一些缺点而应该选择其他选择?
【问题讨论】:
-
一个很好的问题,很久之后才注意到你的存在@fedorqui
-
非常感谢@anubhava,很高兴看到你们这些好人还在!
-
所提出的方法有一些缺点。 (1) 您的第一条记录将包含
$$$$行,如果您的文件不以换行符结尾,则最后一条记录可能 以$$$$结尾。 @anubhava 提出的解决方案有效。如果您想包含空行作为 RS,您甚至可以考虑将其转换为\n*\$\$\$\$\n*。 -
@kvantour 非常好,这就是我正在寻找的洞察力。我做了一些测试,但没有找到这个案例。非常感谢。
-
请注意,当使用@anubhava 定义的
RS时,如果您的文件以RS开头,那么您的第一条记录(FNR==1)将为空。