我正在读关于范围地址在 GNU sed 中。但我不明白它到底是如何工作的,我尝试运行,sed --debug
但输出太冗长而无法理解。
假设我有以下文件input.txt
:
===sep1
Aghroum
===sep2
Thirjeen
===sep3
Ya wedi mata ikinikh
===sep4
Ifoullissen
===sep5
当我尝试按如下方式使用范围地址时:
sed -n '/=/,/=/{/=\|^$/! p}' input.txt
输出是:
# it prints non-empty lines from ===sep1 to ==sep2, and from ===sep3 to ==sep4, etc.
Aghroum
Ya wedi mata ikinikh
据我所知,GNU sed 逐行处理输入文件,为什么它也不匹配范围地址之间==sep2
到==sep3
? (请注意,我不是问如何获取这些行,我知道如何通过使用类似的东西来做到这一点sed -n '/===/!p'
。但我问为什么它不从===sep2
to开始第二个范围地址===sep3
)
谢谢
答案1
此行为的解释见sed
POSIX规范:
具有两个地址的编辑命令应选择从与第一个地址匹配的第一个模式空间到与第二个地址匹配的下一个模式空间的包含范围。 [...] 从选定范围后面的第一行开始,sed将再次查找第一个地址。此后,应重复该过程。
一旦找到一个范围,下一个范围只能从该行开始下列的最早的范围。
换句话说,范围内的结束匹配会“消耗”与其匹配的行;该行无法启动同一范围的另一个实例。
答案2
sed
将按照要求进行操作并按照命令中的规定匹配 from=
到=
sed -n '/=/,/=/{/=\|^$/! p}' input.txt
sed
一次读取每一行。这意味着当找到范围的末尾时,它也不会将该结束范围包含为起始范围。
考虑一下这一点;
===sep1
Aghroum
===sep2
该范围将始终匹配,Aghroum
因为它已到达范围匹配以及文件的末尾。
包含文件的其余部分;
Thirjeen
===sep3
Ya wedi mata ikinikh
===sep4
Ifoullissen
===sep5
匹配再次开始,这次从有 value 的行开始,sep03
直到范围内的下一个匹配=
将输出Ya wedi mata ikinikh
。
由于此后只有一次匹配且范围没有结束,因此该范围内没有其他匹配项,因此匹配退出