匹配最后一个“ Constrained”后,我想打印第6至第10行:
这是我尝试过的:
awk '/Constrained/ { print ; for(n=6; n<10; n++) { getline ; print } }' filename
但是不起作用。 我当时正在考虑使用tail -5仅获得最后5行。 (只有最后一场比赛的6至10)
您可以对此进行测试:
************************** Constrained Symmetrised Forces **************************
* *
* Cartesian components (eV/A) *
* -------------------------------------------------------------------------------- *
* x y z *
* *
* O 1 -0.03440 -0.03440 0.00000 *
* O 2 0.03440 0.03440 -0.00000 *
* O 3 -0.03440 0.03440 -0.00000 *
* O 4 0.03440 -0.03440 0.00000 *
* Ti 1 0.00000 0.00000 0.00000 *
我应该得到以O开头和以Ti结尾的行。但是整个文件中都有几个“受限”
答案 0 :(得分:3)
您需要的是:
grep -A10 Constrained file | tail -n 5
答案 1 :(得分:2)
一个选项:反转文件,找到第一个匹配项加上10行,然后反转,最后5行:
tac filename | grep -B10 Constrained -m 1 | tac | tail -n 5
答案 2 :(得分:2)
tac file | grep "Constrained" -m1 -B10 | tac | tail -n5
tac
会反转文件,因此您可以使用grep -m1
轻松找到最后一个匹配项。其次,您要先处理10行(跳过5行,打印5行)(“之前”,因为输出是相反的)。第二个tac
再次反转输出,因此您将获得原始的行顺序,而tail -n5
隐藏了Constrained
和匹配后要打印的6.行之间的行。
当然,您可以使用简单的grep
来执行此操作,但这将读取并处理整个文件,并且速度可能会大大降低。 tac
从文件末尾开始读取。
grep -A10 "Constrained" file | tail -n5
使用awk(还读取整个文件):
awk '/Constrained/{f=NR;b=""};NR>=f+6 && NR<=f+10{b=b ORS $0}END{print b}' file
搜索“约束”,将初始行号(f
设置为当前行)并删除缓冲区(用于先前的结果)。然后,只要行号与该区域匹配,就将行收集到b
中。
答案 3 :(得分:1)
我想到的最简单的方法是两次读取文件。第一次通过查找匹配的最后一行,第二次通过后显示6-10。
awk 'FNR==NR && /Constrained/ { line=NR }
FNR!=NR && FNR >= line+6 && FNR <= line+10' filename filename
答案 4 :(得分:1)
一次读取文件,但要跟踪缓冲区:
awk '(c-->0){b[10-c]=$0}
/Constrained/{c=10}
END{for(i=6;i<=10;++i) print b[i] }' file
这是如何工作的?
数组b
是缓冲区,在匹配模式/Constrained/
之后总是包含10行。计数器c
将用于递减计数至零。每次找到该模式的匹配项,都会将其重置为最大值10。该程序的工作方式如下:
c
是否大于零并将其减小1(请参见What is the "-->" operator in C++?)。如果满足此条件,则将该行存储在缓冲区b
中。因为我们从9(10-1)开始计数,所以将其存储在位置 10 − i 。这样,比赛之后的行将被索引为1,2,3,...,10。/Constrained/
,则将计数器c
重置为10。b
现在包含匹配后的最后10行。只需打印6至10行即可。几次清理:
不一定要说在匹配模式之后,您有10行,因此必须确保完全擦除了先前的缓冲区。
$ awk '(c-->0){b[10-c]=$0}
/Constrained/{c=10; delete b}
END{for(i=6;i<=10;++i) if (i in b) print b[i] }' file
参数化版本:
参数化版本将允许较大范围。但是想象一下,您想要比赛后的10000至10001行。因此,缓冲区只有两行,实际上会很大。因此,我们可以将其更正为:
$ awk '(c-->min) && (c<=max-min){b[max-c]=$0}
($0~ere){c=max; delete b}
END{for(i=min;i<=max;++i) if (i in b) print b[i] }' \
min=6 max=10 ere="Constrained" file
请注意,min
必须大于0。
原理证明:
$ awk '(c-->0) && (c<=max-min){b[max-c]=$0}
($0~ere){ c=max; delete b}
END{for(i=min;i<=max;i++) if(i in b) print b[i] }' \
min=6 max=10 ere="20" <( seq 1 50 && seq 101 150 )
126
127
128
129
130
答案 5 :(得分:0)
我建议尝试这个。 -A表示单词匹配后的10行。 -m表示何时停止读取文件。我们不想读取整个文件。你呢?
grep -A10 Constrained file | tail -5