1 2 PAT1 3 - first block 4 PAT2 5 6 PAT1 7 - second block PAT2 8 9 PAT1 10 - third block
我已经读了How to select lines between two marker patterns which may occur multiple times with awk/sed,但我很好奇地看到这一切的所有可能的组合,无论打印模式还是不打印.
如何选择两种图案之间的线条?
$awk '/PAT1/,/PAT2/' file PAT1 3 - first block 4 PAT2 PAT1 7 - second block PAT2 PAT1 10 - third block
或者,使用变量:
awk '/PAT1/{flag=1} flag; /PAT2/{flag=0}' file
这个怎么用?
> / PAT1 /匹配具有此文本的行,以及/ PAT2 /.
> / PAT1 / {flag = 1}在行中找到文本PAT1时设置标志.
> / PAT2 / {flag = 0}在行中找到文本PAT2时取消标志.
> flag是一个带有默认动作的模式,它是打印$0:如果flag等于1,则打印行.这样,它将打印从PAT1发生时发生的所有行,直到看到下一个PAT2.这也将打印从PAT1的最后一个匹配到文件末尾的行.
PAT1和PAT2之间的打印行 – 不包括PAT1和PAT2
$awk '/PAT1/{flag=1; next} /PAT2/{flag=0} flag' file 3 - first block 4 7 - second block 10 - third block
这将使用next跳过包含PAT1的行,以避免打印.
这个调用next可以通过重组块来删除:awk’/ PAT2 / {flag = 0} flag; / PAT1 / {flag = 1}’文件.
PAT1和PAT2之间的打印行 – 包括PAT1
$awk '/PAT1/{flag=1} /PAT2/{flag=0} flag' file PAT1 3 - first block 4 PAT1 7 - second block PAT1 10 - third block
通过将标志置于最后,它触发在PAT1或PAT2上设置的操作:在PAT1上打印,而不是在PAT2上打印.
PAT1和PAT2之间的打印行 – 包括PAT2
$awk 'flag; /PAT1/{flag=1} /PAT2/{flag=0}' file 3 - first block 4 PAT2 7 - second block PAT2 10 - third block
通过将标志置于一开始,它触发先前设置的动作,因此打印关闭模式,而不是初始化模式.
在PAT1和PAT2之间打印行 – 如果不发生其他PAT2,则不包括从最后一个PAT1到文件末尾的行
awk 'flag{ if (/PAT2/) {printf "%s",buf; flag=0; buf=""} else buf = buf $0 ORS } /PAT1/ {flag=1}' file
作为单行:
$awk 'flag{ if (/PAT2/){printf "%s",buf; flag=0; buf=""} else buf = buf $0 ORS}; /PAT1/{flag=1}' file 3 - first block 4 7 - second block # note the lack of third block,since no other PAT2 happens after it
这样可以将所有选定的行保留在从PAT1找到的位置开始填充的缓冲区中.然后,它保持填充以下行直到找到PAT2.在这一点上,它打印存储的内容并清空缓冲区.